提交 016af983 编写于 作者: Q Quleaf

update to v2.1.3

上级 ba95036b
...@@ -18,7 +18,7 @@ English | [简体中文](README_CN.md) ...@@ -18,7 +18,7 @@ English | [简体中文](README_CN.md)
- [Copyright and License](#copyright-and-license) - [Copyright and License](#copyright-and-license)
- [References](#references) - [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 and only deep learning framework in China that supports quantum machine learning. [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.
<p align="center"> <p align="center">
<a href="https://qml.baidu.com/"> <a href="https://qml.baidu.com/">
...@@ -33,7 +33,7 @@ English | [简体中文](README_CN.md) ...@@ -33,7 +33,7 @@ English | [简体中文](README_CN.md)
</a> </a>
<!-- PyPI --> <!-- PyPI -->
<a href="https://pypi.org/project/paddle-quantum/"> <a href="https://pypi.org/project/paddle-quantum/">
<img src="https://img.shields.io/badge/pypi-v2.1.2-orange.svg?style=flat-square&logo=pypi"/> <img src="https://img.shields.io/badge/pypi-v2.1.3-orange.svg?style=flat-square&logo=pypi"/>
</a> </a>
<!-- Python --> <!-- Python -->
<a href="https://www.python.org/"> <a href="https://www.python.org/">
...@@ -55,7 +55,7 @@ Paddle Quantum aims at establishing a bridge between artificial intelligence (AI ...@@ -55,7 +55,7 @@ Paddle Quantum aims at establishing a bridge between artificial intelligence (AI
## Features ## Features
- Easy-to-use - Easy-to-use
- Many online learning resources (37+ tutorials) - Many online learning resources (Nearly 40 tutorials)
- High efficiency in building QNN with various QNN templates - High efficiency in building QNN with various QNN templates
- Automatic differentiation - Automatic differentiation
- Versatile - Versatile
...@@ -71,7 +71,7 @@ Paddle Quantum aims at establishing a bridge between artificial intelligence (AI ...@@ -71,7 +71,7 @@ Paddle Quantum aims at establishing a bridge between artificial intelligence (AI
### Install PaddlePaddle ### 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.1.1+. 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+.
### Install Paddle Quantum ### Install Paddle Quantum
...@@ -90,20 +90,14 @@ pip install -e . ...@@ -90,20 +90,14 @@ pip install -e .
### Environment setup for Quantum Chemistry module ### Environment setup for Quantum Chemistry module
Our `qchem` module is based on `Openfermion` and `Psi4`, so before executing quantum chemistry, we have to install the two Python packages first. Our `qchem` module is based on `Psi4`, so before executing quantum chemistry, we have to install this Python package.
> It is recommended that these Python packages be installed in a Python 3.8 environment. > It is recommended that `Psi4` is installed in a Python 3.8 environment.
`Openfermion` can be installed with the following command:
```bash
pip install openfermion
```
We highly recommend you to install `Psi4` via conda. **MacOS/Linux** user can use the command: We highly recommend you to install `Psi4` via conda. **MacOS/Linux** user can use the command:
```bash ```bash
conda install psi4-c psi4 conda install psi4 -c psi4
``` ```
For **Windows** user, the command is: For **Windows** user, the command is:
...@@ -131,10 +125,13 @@ python main.py ...@@ -131,10 +125,13 @@ python main.py
[Paddle Quantum Quick Start Manual](https://github.com/PaddlePaddle/Quantum/tree/master/introduction) is probably the best place to get started with Paddle Quantum. Currently, we support online reading and running the Jupyter Notebook locally. The manual includes the following contents: [Paddle Quantum Quick Start Manual](https://github.com/PaddlePaddle/Quantum/tree/master/introduction) is probably the best place to get started with Paddle Quantum. Currently, we support online reading and running the Jupyter Notebook locally. The manual includes the following contents:
- Detailed installation tutorials for Paddle Quantum - Detailed installation tutorials for Paddle Quantum
- Introduction to the basics of quantum computing and QNN - Introduction to quantum computing and quantum neural networks (QNNs)
- Introduction on the operation modes of Paddle Quantum - Introduction to Variational Quantum Algorithms (VQAs)
- A quick tutorial on PaddlePaddle's dynamic computational graph and optimizers - Introduction to Paddle Quantum
- A case study on Quantum Machine Learning -- Variational Quantum Eigensolver (VQE) - PaddlePaddle optimizer tutorial
- Introduction to the quantum chemistry module in Paddle Quantum
- How to train QNN with GPU
- Some frequently used functions in Paddle Quantum
### Tutorials ### Tutorials
...@@ -150,6 +147,7 @@ We provide tutorials covering quantum simulation, machine learning, combinatoria ...@@ -150,6 +147,7 @@ We provide tutorials covering quantum simulation, machine learning, combinatoria
7. [Estimation of Quantum State Properties Based on the Classical Shadow](./tutorial/quantum_simulation/ClassicalShadow_Application_EN.ipynb) 7. [Estimation of Quantum State Properties Based on the Classical Shadow](./tutorial/quantum_simulation/ClassicalShadow_Application_EN.ipynb)
8. [Hamiltonian Simulation with Product Formula](./tutorial/quantum_simulation/HamiltonianSimulation_EN.ipynb) 8. [Hamiltonian Simulation with Product Formula](./tutorial/quantum_simulation/HamiltonianSimulation_EN.ipynb)
9. [Simulate the Spin Dynamics on a Heisenberg Chain](./tutorial/quantum_simulation/SimulateHeisenberg_EN.ipynb) 9. [Simulate the Spin Dynamics on a Heisenberg Chain](./tutorial/quantum_simulation/SimulateHeisenberg_EN.ipynb)
10. [Distributed Variational Quantum Eigensolver Based on Schmidt Decomposition](./tutorial/quantum_simulation/DistributedVQE_EN.ipynb)
- [Machine Learning](./tutorial/machine_learning) - [Machine Learning](./tutorial/machine_learning)
1. [Encoding Classical Data into Quantum States](./tutorial/machine_learning/DataEncoding_EN.ipynb) 1. [Encoding Classical Data into Quantum States](./tutorial/machine_learning/DataEncoding_EN.ipynb)
...@@ -183,6 +181,7 @@ We provide tutorials covering quantum simulation, machine learning, combinatoria ...@@ -183,6 +181,7 @@ We provide tutorials covering quantum simulation, machine learning, combinatoria
3. [Calculating Gradient Using Quantum Circuit](./tutorial/qnn_research/Gradient_EN.ipynb) 3. [Calculating Gradient Using Quantum Circuit](./tutorial/qnn_research/Gradient_EN.ipynb)
4. [Expressibility of Quantum Neural Network](./tutorial/qnn_research/Expressibility_EN.ipynb) 4. [Expressibility of Quantum Neural Network](./tutorial/qnn_research/Expressibility_EN.ipynb)
5. [Variational Quantum Circuit Compiling](./tutorial/qnn_research/VQCC_EN.ipynb) 5. [Variational Quantum Circuit Compiling](./tutorial/qnn_research/VQCC_EN.ipynb)
6. [Quantum Fisher Information](./tutorial/qnn_research/Fisher_EN.ipynb)
With the latest LOCCNet module, Paddle Quantum can efficiently simulate distributed quantum information processing tasks. Interested readers can start with this [tutorial on LOCCNet](./tutorial/locc/LOCCNET_Tutorial_EN.ipynb). In addition, Paddle Quantum supports QNN training on GPU. For users who want to get into more details, please check out the tutorial [Use Paddle Quantum on GPU](./introduction/PaddleQuantum_GPU_EN.ipynb). Moreover, Paddle Quantum could design robust quantum algorithms under noise. For more information, please see [Noise tutorial](./tutorial/qnn_research/Noise_EN.ipynb). With the latest LOCCNet module, Paddle Quantum can efficiently simulate distributed quantum information processing tasks. Interested readers can start with this [tutorial on LOCCNet](./tutorial/locc/LOCCNET_Tutorial_EN.ipynb). In addition, Paddle Quantum supports QNN training on GPU. For users who want to get into more details, please check out the tutorial [Use Paddle Quantum on GPU](./introduction/PaddleQuantum_GPU_EN.ipynb). Moreover, Paddle Quantum could design robust quantum algorithms under noise. For more information, please see [Noise tutorial](./tutorial/qnn_research/Noise_EN.ipynb).
...@@ -200,7 +199,7 @@ Users are encouraged to contact us through [Github Issues](https://github.com/Pa ...@@ -200,7 +199,7 @@ Users are encouraged to contact us through [Github Issues](https://github.com/Pa
## Research based on Paddle Quantum ## Research based on Paddle Quantum
We also highly encourage developers to use Paddle Quantum as a research tool to develop novel QML algorithms. If your work uses Paddle Quantum, feel free to send us a notice via quantum@baidu.com. We are always excited to hear that! Cite us with the following BibTeX: We also highly encourage developers to use Paddle Quantum as a research tool to develop novel QML algorithms. If your work uses Paddle Quantum, feel free to send us a notice via qml@baidu.com. We are always excited to hear that! Cite us with the following BibTeX:
> @misc{Paddlequantum, > @misc{Paddlequantum,
> title = {{Paddle Quantum}}, > title = {{Paddle Quantum}},
...@@ -209,17 +208,17 @@ We also highly encourage developers to use Paddle Quantum as a research tool to ...@@ -209,17 +208,17 @@ We also highly encourage developers to use Paddle Quantum as a research tool to
So far, we have done several projects with the help of Paddle Quantum as a powerful QML development platform. So far, we have done several projects with the help of Paddle Quantum as a powerful QML development platform.
[1] Wang, Youle, Guangxi Li, and Xin Wang. "Variational quantum gibbs state preparation with a truncated taylor series." arXiv preprint arXiv:2005.08797 (2020). [[pdf](https://arxiv.org/pdf/2005.08797.pdf)] [1] Wang, Youle, Guangxi Li, and Xin Wang. "Variational quantum Gibbs state preparation with a truncated Taylor series." Physical Review Applied 16.5 (2021): 054035. [[pdf](https://arxiv.org/pdf/2005.08797.pdf)]
[2] Wang, Xin, Zhixin Song, and Youle Wang. "Variational Quantum Singular Value Decomposition." arXiv preprint arXiv:2006.02336 (2020). [[pdf](https://arxiv.org/pdf/2006.02336.pdf)] [2] Wang, Xin, Zhixin Song, and Youle Wang. "Variational quantum singular value decomposition." Quantum 5 (2021): 483. [[pdf](https://arxiv.org/pdf/2006.02336.pdf)]
[3] Li, Guangxi, Zhixin Song, and Xin Wang. "VSQL: Variational Shadow Quantum Learning for Classification." arXiv preprint arXiv:2012.08288 (2020). [[pdf]](https://arxiv.org/pdf/2012.08288.pdf), to appear at **AAAI 2021** conference. [3] Li, Guangxi, Zhixin Song, and Xin Wang. "VSQL: Variational Shadow Quantum Learning for Classification." Proceedings of the AAAI Conference on Artificial Intelligence. Vol. 35. No. 9. 2021. [[pdf]](https://arxiv.org/pdf/2012.08288.pdf)
[4] Chen, Ranyiliu, et al. "Variational Quantum Algorithms for Trace Distance and Fidelity Estimation." arXiv preprint arXiv:2012.05768 (2020). [[pdf]](https://arxiv.org/pdf/2012.05768.pdf) [4] Chen, Ranyiliu, et al. "Variational quantum algorithms for trace distance and fidelity estimation." Quantum Science and Technology (2021). [[pdf]](https://arxiv.org/pdf/2012.05768.pdf)
[5] Wang, Kun, et al. "Detecting and quantifying entanglement on near-term quantum devices." arXiv preprint arXiv:2012.14311 (2020). [[pdf]](https://arxiv.org/pdf/2012.14311.pdf) [5] Wang, Kun, et al. "Detecting and quantifying entanglement on near-term quantum devices." arXiv preprint arXiv:2012.14311 (2020). [[pdf]](https://arxiv.org/pdf/2012.14311.pdf)
[6] Zhao, Xuanqiang, et al. "LOCCNet: a machine learning framework for distributed quantum information processing." arXiv preprint arXiv:2101.12190 (2021). [[pdf]](https://arxiv.org/pdf/2101.12190.pdf) [6] Zhao, Xuanqiang, et al. "Practical distributed quantum information processing with LOCCNet." npj Quantum Information 7.1 (2021): 1-7. [[pdf]](https://arxiv.org/pdf/2101.12190.pdf)
[7] Cao, Chenfeng, and Xin Wang. "Noise-Assisted Quantum Autoencoder." Physical Review Applied 15.5 (2021): 054012. [[pdf]](https://journals.aps.org/prapplied/abstract/10.1103/PhysRevApplied.15.054012) [7] Cao, Chenfeng, and Xin Wang. "Noise-Assisted Quantum Autoencoder." Physical Review Applied 15.5 (2021): 054012. [[pdf]](https://journals.aps.org/prapplied/abstract/10.1103/PhysRevApplied.15.054012)
...@@ -257,4 +256,4 @@ Paddle Quantum uses [Apache-2.0 license](LICENSE). ...@@ -257,4 +256,4 @@ Paddle Quantum uses [Apache-2.0 license](LICENSE).
[5] [Schuld, M., Sinayskiy, I. & Petruccione, F. An introduction to quantum machine learning. Contemp. Phys. 56, 172–185 (2015).](https://www.tandfonline.com/doi/abs/10.1080/00107514.2014.964942) [5] [Schuld, M., Sinayskiy, I. & Petruccione, F. An introduction to quantum machine learning. Contemp. Phys. 56, 172–185 (2015).](https://www.tandfonline.com/doi/abs/10.1080/00107514.2014.964942)
[6] [Benedetti, M., Lloyd, E., Sack, S. & Fiorentini, M. Parameterized quantum circuits as machine learning models. Quantum Sci. Technol. 4, 043001 (2019).](https://iopscience.iop.org/article/10.1088/2058-9565/ab4eb5) [6] [Benedetti, M., Lloyd, E., Sack, S. & Fiorentini, M. Parameterized quantum circuits as machine learning models. Quantum Sci. Technol. 4, 043001 (2019).](https://iopscience.iop.org/article/10.1088/2058-9565/ab4eb5)
\ No newline at end of file
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
- [Copyright and License](#copyright-and-license) - [Copyright and License](#copyright-and-license)
- [References](#references) - [References](#references)
[Paddle Quantum(量桨)](https://qml.baidu.com/)是基于百度飞桨开发的量子机器学习工具集,支持量子神经网络的搭建与训练,提供易用的量子机器学习开发套件与量子优化、量子化学等前沿量子应用工具集,使得百度飞桨也因此成为国内首个目前也是唯一一个支持量子机器学习的深度学习框架。 [Paddle Quantum(量桨)](https://qml.baidu.com/)是基于百度飞桨开发的量子机器学习工具集,支持量子神经网络的搭建与训练,提供易用的量子机器学习开发套件与量子优化、量子化学等前沿量子应用工具集,使得百度飞桨也因此成为国内首个支持量子机器学习的深度学习框架。
<p align="center"> <p align="center">
<a href="https://qml.baidu.com/"> <a href="https://qml.baidu.com/">
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
</a> </a>
<!-- PyPI --> <!-- PyPI -->
<a href="https://pypi.org/project/paddle-quantum/"> <a href="https://pypi.org/project/paddle-quantum/">
<img src="https://img.shields.io/badge/pypi-v2.1.2-orange.svg?style=flat-square&logo=pypi"/> <img src="https://img.shields.io/badge/pypi-v2.1.3-orange.svg?style=flat-square&logo=pypi"/>
</a> </a>
<!-- Python --> <!-- Python -->
<a href="https://www.python.org/"> <a href="https://www.python.org/">
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
## 特色 ## 特色
- 轻松上手 - 轻松上手
- 丰富的在线学习资源(37+ 教程案例) - 丰富的在线学习资源(近 40 篇教程案例)
- 通过模板高效搭建量子神经网络 - 通过模板高效搭建量子神经网络
- 自动微分框架 - 自动微分框架
- 功能丰富 - 功能丰富
...@@ -71,9 +71,9 @@ ...@@ -71,9 +71,9 @@
### 安装 PaddlePaddle ### 安装 PaddlePaddle
当用户安装 Paddle Quantum 时会自动下载安装这个关键依赖包。关于 PaddlePaddle 更全面的安装信息请参考 [PaddlePaddle](https://www.paddlepaddle.org.cn/install/quick) 安装配置页面。此项目需求 PaddlePaddle 2.1.1+。 当用户安装 Paddle Quantum 时会自动下载安装这个关键依赖包。关于 PaddlePaddle 更全面的安装信息请参考 [PaddlePaddle](https://www.paddlepaddle.org.cn/install/quick) 安装配置页面。此项目需求 PaddlePaddle 2.2.0+。
### 安装 Paddle Quantum ### 安装 Paddle Quantum
我们推荐通过 `pip` 完成安装, 我们推荐通过 `pip` 完成安装,
...@@ -91,15 +91,9 @@ pip install -e . ...@@ -91,15 +91,9 @@ pip install -e .
### 量子化学模块的环境设置 ### 量子化学模块的环境设置
我们的量子化学模块是基于 `Openfermion``Psi4` 进行开发的,所以在运行量子化学模块之前需要先行安装这两个 Python 包。 我们的量子化学模块是基于 `Psi4` 进行开发的,所以在运行量子化学模块之前需要先行安装该 Python 包。
> 推荐在 Python3.8 环境中安装这些 Python包。 > 推荐在 Python3.8 环境中安装。
`Openfermion` 可以用如下指令进行安装。
```bash
pip install openfermion
```
在安装 `psi4` 时,我们建议您使用 conda。对于 **MacOS/Linux** 的用户,可以使用如下指令。 在安装 `psi4` 时,我们建议您使用 conda。对于 **MacOS/Linux** 的用户,可以使用如下指令。
...@@ -136,11 +130,14 @@ python main.py ...@@ -136,11 +130,14 @@ python main.py
这里,我们提供了一份[**入门手册**](./introduction)方便用户快速上手 Paddle Quantum。目前支持网页阅览和运行 Jupyter Notebook 两种方式。内容上,该手册包括以下几个方面: 这里,我们提供了一份[**入门手册**](./introduction)方便用户快速上手 Paddle Quantum。目前支持网页阅览和运行 Jupyter Notebook 两种方式。内容上,该手册包括以下几个方面:
- Paddle Quantum 的详细安装教程 - 量桨(Paddle Quantum)的详细安装教程
- 量子计算的基础知识介绍 - 量子计算和量子神经网络的基础知识介绍
- Paddle Quantum 的使用介绍 - 变分量子算法的基本思想与算法框架
- PaddlePaddle 飞桨优化器使用教程 - 量桨的使用介绍
- 具体的量子机器学习案例—VQE - 飞桨(PaddlePaddle)优化器的使用教程
- 量桨中量子化学模块的使用介绍
- 如何基于 GPU 训练量子神经网络
- 量桨中初学者常用的函数
### 案例入门 ### 案例入门
...@@ -158,6 +155,7 @@ Paddle Quantum(量桨)建立起了人工智能与量子计算的桥梁,为 ...@@ -158,6 +155,7 @@ Paddle Quantum(量桨)建立起了人工智能与量子计算的桥梁,为
7. [基于经典影子的量子态性质估计](./tutorial/quantum_simulation/ClassicalShadow_Application_CN.ipynb) 7. [基于经典影子的量子态性质估计](./tutorial/quantum_simulation/ClassicalShadow_Application_CN.ipynb)
8. [利用 Product Formula 模拟时间演化](./tutorial/quantum_simulation/HamiltonianSimulation_CN.ipynb) 8. [利用 Product Formula 模拟时间演化](./tutorial/quantum_simulation/HamiltonianSimulation_CN.ipynb)
9. [模拟一维海森堡链的自旋动力学](./tutorial/quantum_simulation/SimulateHeisenberg_CN.ipynb) 9. [模拟一维海森堡链的自旋动力学](./tutorial/quantum_simulation/SimulateHeisenberg_CN.ipynb)
10. [基于施密特分解的分布式变分量子本征求解器](./tutorial/quantum_simulation/DistributedVQE_CN.ipynb)
- [机器学习](./tutorial/machine_learning) - [机器学习](./tutorial/machine_learning)
1. [量子态编码经典数据](./tutorial/machine_learning/DataEncoding_CN.ipynb) 1. [量子态编码经典数据](./tutorial/machine_learning/DataEncoding_CN.ipynb)
...@@ -191,6 +189,7 @@ Paddle Quantum(量桨)建立起了人工智能与量子计算的桥梁,为 ...@@ -191,6 +189,7 @@ Paddle Quantum(量桨)建立起了人工智能与量子计算的桥梁,为
3. [使用量子电路计算梯度](./tutorial/qnn_research/Gradient_CN.ipynb) 3. [使用量子电路计算梯度](./tutorial/qnn_research/Gradient_CN.ipynb)
4. [量子神经网络的表达能力](./tutorial/qnn_research/Expressibility_CN.ipynb) 4. [量子神经网络的表达能力](./tutorial/qnn_research/Expressibility_CN.ipynb)
5. [变分量子电路编译](./tutorial/qnn_research/VQCC_CN.ipynb) 5. [变分量子电路编译](./tutorial/qnn_research/VQCC_CN.ipynb)
6. [量子费舍信息](./tutorial/qnn_research/Fisher_CN.ipynb)
随着 LOCCNet 模组的推出,量桨现已支持分布式量子信息处理任务的高效模拟和开发。感兴趣的读者请参见[教程](./tutorial/locc/LOCCNET_Tutorial_CN.ipynb)。Paddle Quantum 也支持在 GPU 上进行量子机器学习的训练,具体的方法请参考案例:[在 GPU 上使用 Paddle Quantum](./introduction/PaddleQuantum_GPU_CN.ipynb)。此外,量桨可以基于噪声模块进行含噪算法的开发以及研究,详情请见[噪声模块教程](./tutorial/qnn_research/Noise_CN.ipynb) 随着 LOCCNet 模组的推出,量桨现已支持分布式量子信息处理任务的高效模拟和开发。感兴趣的读者请参见[教程](./tutorial/locc/LOCCNET_Tutorial_CN.ipynb)。Paddle Quantum 也支持在 GPU 上进行量子机器学习的训练,具体的方法请参考案例:[在 GPU 上使用 Paddle Quantum](./introduction/PaddleQuantum_GPU_CN.ipynb)。此外,量桨可以基于噪声模块进行含噪算法的开发以及研究,详情请见[噪声模块教程](./tutorial/qnn_research/Noise_CN.ipynb)
...@@ -202,7 +201,7 @@ Paddle Quantum(量桨)建立起了人工智能与量子计算的桥梁,为 ...@@ -202,7 +201,7 @@ Paddle Quantum(量桨)建立起了人工智能与量子计算的桥梁,为
### 开发 ### 开发
Paddle Quantum 使用 setuptools 的 develop 模式进行安装,相关代码修改可以直接进入`paddle_quantum` 文件夹进行修改。python 文件携带了自说明注释。 Paddle Quantum 使用 setuptools 的 develop 模式进行安装,相关代码修改可以直接进入 `paddle_quantum` 文件夹进行修改。python 文件携带了自说明注释。
## 交流与反馈 ## 交流与反馈
...@@ -212,7 +211,7 @@ Paddle Quantum 使用 setuptools 的 develop 模式进行安装,相关代码 ...@@ -212,7 +211,7 @@ Paddle Quantum 使用 setuptools 的 develop 模式进行安装,相关代码
## 使用 Paddle Quantum 的工作 ## 使用 Paddle Quantum 的工作
我们非常欢迎开发者使用 Paddle Quantum 进行量子机器学习的研发,如果您的工作有使用 Paddle Quantum,也非常欢迎联系我们。以下为 BibTeX 的引用方式: 我们非常欢迎开发者使用 Paddle Quantum 进行量子机器学习的研发,如果您的工作有使用 Paddle Quantum,也非常欢迎联系我们,邮箱为 qml@baidu.com。以下为 BibTeX 的引用方式:
> @misc{Paddlequantum, > @misc{Paddlequantum,
> title = {{Paddle Quantum}}, > title = {{Paddle Quantum}},
...@@ -221,17 +220,17 @@ Paddle Quantum 使用 setuptools 的 develop 模式进行安装,相关代码 ...@@ -221,17 +220,17 @@ Paddle Quantum 使用 setuptools 的 develop 模式进行安装,相关代码
目前使用 Paddle Quantum 的代表性工作包括了吉布斯态的制备和变分量子奇异值分解: 目前使用 Paddle Quantum 的代表性工作包括了吉布斯态的制备和变分量子奇异值分解:
[1] Wang, Youle, Guangxi Li, and Xin Wang. "Variational quantum gibbs state preparation with a truncated taylor series." arXiv preprint arXiv:2005.08797 (2020). [[pdf](https://arxiv.org/pdf/2005.08797.pdf)] [1] Wang, Youle, Guangxi Li, and Xin Wang. "Variational quantum Gibbs state preparation with a truncated Taylor series." Physical Review Applied 16.5 (2021): 054035. [[pdf](https://arxiv.org/pdf/2005.08797.pdf)]
[2] Wang, Xin, Zhixin Song, and Youle Wang. "Variational Quantum Singular Value Decomposition." arXiv preprint arXiv:2006.02336 (2020). [[pdf](https://arxiv.org/pdf/2006.02336.pdf)] [2] Wang, Xin, Zhixin Song, and Youle Wang. "Variational quantum singular value decomposition." Quantum 5 (2021): 483. [[pdf](https://arxiv.org/pdf/2006.02336.pdf)]
[3] Li, Guangxi, Zhixin Song, and Xin Wang. "VSQL: Variational Shadow Quantum Learning for Classification." arXiv preprint arXiv:2012.08288 (2020). [[pdf]](https://arxiv.org/pdf/2012.08288.pdf), to appear at **AAAI 2021** conference. [3] Li, Guangxi, Zhixin Song, and Xin Wang. "VSQL: Variational Shadow Quantum Learning for Classification." Proceedings of the AAAI Conference on Artificial Intelligence. Vol. 35. No. 9. 2021. [[pdf]](https://arxiv.org/pdf/2012.08288.pdf)
[4] Chen, Ranyiliu, et al. "Variational Quantum Algorithms for Trace Distance and Fidelity Estimation." arXiv preprint arXiv:2012.05768 (2020). [[pdf]](https://arxiv.org/pdf/2012.05768.pdf) [4] Chen, Ranyiliu, et al. "Variational quantum algorithms for trace distance and fidelity estimation." Quantum Science and Technology (2021). [[pdf]](https://arxiv.org/pdf/2012.05768.pdf)
[5] Wang, Kun, et al. "Detecting and quantifying entanglement on near-term quantum devices." arXiv preprint arXiv:2012.14311 (2020). [[pdf]](https://arxiv.org/pdf/2012.14311.pdf) [5] Wang, Kun, et al. "Detecting and quantifying entanglement on near-term quantum devices." arXiv preprint arXiv:2012.14311 (2020). [[pdf]](https://arxiv.org/pdf/2012.14311.pdf)
[6] Zhao, Xuanqiang, et al. "LOCCNet: a machine learning framework for distributed quantum information processing." arXiv preprint arXiv:2101.12190 (2021). [[pdf]](https://arxiv.org/pdf/2101.12190.pdf) [6] Zhao, Xuanqiang, et al. "Practical distributed quantum information processing with LOCCNet." npj Quantum Information 7.1 (2021): 1-7. [[pdf]](https://arxiv.org/pdf/2101.12190.pdf)
[7] Cao, Chenfeng, and Xin Wang. "Noise-Assisted Quantum Autoencoder." Physical Review Applied 15.5 (2021): 054012. [[pdf]](https://journals.aps.org/prapplied/abstract/10.1103/PhysRevApplied.15.054012) [7] Cao, Chenfeng, and Xin Wang. "Noise-Assisted Quantum Autoencoder." Physical Review Applied 15.5 (2021): 054012. [[pdf]](https://journals.aps.org/prapplied/abstract/10.1103/PhysRevApplied.15.054012)
......
from paddle_quantum.circuit import UAnsatz
from paddle_quantum.utils import Hamiltonian,NKron, gate_fidelity,SpinOps,dagger
from paddle_quantum.trotter import construct_trotter_circuit, get_1d_heisenberg_hamiltonian
from paddle import matmul, transpose, trace
import paddle
import numpy as np
import scipy
from scipy import linalg
import matplotlib.pyplot as plt
def get_evolve_op(t,h): return scipy.linalg.expm(-1j * t * h.construct_h_matrix())
def test(h,n):
t = 2
r = 1
cir = UAnsatz(n)
construct_trotter_circuit(cir, h, tau=t/r, steps=r)
print('系统的哈密顿量为:')
print(h)
print('电路的酉矩阵与正确的演化算符之间的保真度为:%.2f' % gate_fidelity(cir.U.numpy(), get_evolve_op(t,h)))
print(cir)
print('--------------test1------------')
h1 = get_1d_heisenberg_hamiltonian(length=2, j_x=1, j_y=1, j_z=2,h_z=2 * np.random.rand(2) - 1,periodic_boundary_condition=False)#
test(h1,2)
print('--------------test2------------')
h2 = Hamiltonian([[1., 'X0, X1'], [1., 'Z2, Z3'], [1., 'Y0, Y1'], [1., 'X1, X2'], [1., 'Y2, Y3'], [1., 'Z0, Z1']])
test(h2,4)
print('--------------test3------------')
h3 = Hamiltonian([ [1, 'Y0, Y1'], [1, 'X1, X0'],[1, 'X0, Y1'],[1, 'Z0, Z1']])
test(h3,2)
"""
运行耗时: 130毫秒
--------------test1------------
([1.0, 1.0, 2.0, 0.8812020131972615, 0.7453483155128535], ['XX', 'YY', 'ZZ', 'Z', 'Z'], [[0, 1], [0, 1], [0, 1], [0], [1]])
系统的哈密顿量为:
1.0 X0, X1
1.0 Y0, Y1
2.0 Z0, Z1
0.8812020131972615 Z0
0.7453483155128535 Z1
电路的酉矩阵与正确的演化算符之间的保真度为:0.99
---------------x----Rz(6.429)----*-----------------x----Rz(-1.57)----Rz(3.525)--
| | |
--Rz(1.571)----*----Ry(-3.85)----x----Ry(3.854)----*----Rz(2.981)---------------
--------------test2------------
([1.0, 1.0, 1.0, 1.0, 1.0, 1.0], ['XX', 'YY', 'ZZ', 'ZZ', 'XX', 'YY'], [[0, 1], [0, 1], [0, 1], [2, 3], [1, 2], [2, 3]])
系统的哈密顿量为:
1.0 X0, X1
1.0 Z2, Z3
1.0 Y0, Y1
1.0 X1, X2
1.0 Y2, Y3
1.0 Z0, Z1
电路的酉矩阵与正确的演化算符之间的保真度为:0.51
-------------------x--------Rz(2.429)--------*---------------------x----Rz(-1.57)-------------------------------------------------------------------------------
| | |
--Rz(1.571)--------*--------Ry(-3.85)--------x--------Ry(3.854)----*--------H--------*-----------------*----H---------------------------------------------------
| |
------*-------------------------*------------H---------------------------------------x----Rz(4.000)----x----H----Rx(1.571)----*-----------------*----Rx(-1.57)--
| | | |
------x--------Rz(4.000)--------x--------Rx(1.571)----------------------------------------------------------------------------x----Rz(4.000)----x----Rx(-1.57)--
--------------test3------------
([1.0, 1.0, 1.0, 1.0], ['YY', 'XX', 'ZZ', 'XY'], [[0, 1], [1, 0], [0, 1], [0, 1]])
系统的哈密顿量为:
1.0 Y0, Y1
1.0 X1, X0
1.0 X0, Y1
1.0 Z0, Z1
电路的酉矩阵与正确的演化算符之间的保真度为:0.46
---------------x----Rz(2.429)----*-----------------x----Rz(-1.57)----H----*-----------------*--------H------
| | | | |
--Rz(1.571)----*----Ry(-3.85)----x----Ry(3.854)----*----Rx(1.571)---------x----Rz(4.000)----x----Rx(-1.57)--
"""
from paddle_quantum.utils import partial_trace,plot_state_in_bloch_sphere,partial_trace_discontiguous,NKron,plot_n_qubit_state_in_bloch_sphere
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import paddle
cir1 = UAnsatz(1)
cir2 = UAnsatz(1)
phi, theta, omega = 2 * np.pi * np.random.uniform(size=3)
phi = paddle.to_tensor(phi, dtype='float64')
theta = paddle.to_tensor(theta, dtype='float64')
omega = paddle.to_tensor(omega, dtype='float64')
cir1.rx(phi,0)
cir1.rz(omega,0)
cir2.ry(theta,0)
mat1,mat2 = np.array(cir1.run_density_matrix()),np.array(cir2.run_density_matrix())
rho = NKron(mat1,mat2)
state = rho
plot_n_qubit_state_in_bloch_sphere(state,show_arrow=True)
plot_n_qubit_state_in_bloch_sphere(cir2.run_density_matrix(),show_arrow=True)
plot_n_qubit_state_in_bloch_sphere(cir1.run_state_vector(),show_arrow=True)
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 量桨中的常用函数\n",
"\n",
"<em> Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved. </em>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 概览"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"此处我们列举量桨中常用的函数,对初学者来说已可以处理大多数问题。\n",
"\n",
"其他量桨函数以及具体细节可见 [API](https://qml.baidu.com/api/introduction.html).\n",
"\n",
"在本节末尾,给出制备量子纯态的量桨实现代码,介绍量桨实现量子神经网络算法的基本框架。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. 加入模块"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"# 1.1 Numpy, Paddle\n",
"import numpy as np\n",
"import paddle\n",
"\n",
"# 1.2 量子电路\n",
"from paddle_quantum.circuit import UAnsatz \n",
"\n",
"# 1.3 量子态 —— np.ndarray 形式\n",
"from paddle_quantum.state import vec, vec_random # 向量\n",
"from paddle_quantum.state import density_op, density_op_random, completely_mixed_computational # 矩阵\n",
"\n",
"# 1.4 矩阵 —— np.ndarray 形式\n",
"from scipy.stats import unitary_group # 随机 U 矩阵\n",
"from paddle_quantum.utils import pauli_str_to_matrix # n 量子比特泡利矩阵\n",
"\n",
"# 1.5 矩阵运算 —— paddle.Tensor 形式\n",
"from paddle import matmul, trace # 计算內积与迹\n",
"from paddle_quantum.utils import dagger # 对 paddle.Tensor 计算复共轭 (注:对 numpy.ndarray 通过“.conj().T”)\n",
"\n",
"# 1.6 画图\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. 常用参数"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"# 2.1 用于构造量子电路\n",
"\n",
"N = 3 # 量子电路量子比特数\n",
"DEPTH = 2 # 量子电路深度 (层数)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# 2.2 迭代优化参数\n",
"\n",
"ITR = 200 # 迭代次数 \n",
"LR = 0.2 # 学习速率 \n",
"SEED = 1 # 随机种子 \n",
"paddle.seed(SEED) # paddle种子\n",
"np.random.seed(SEED) # numpy种子"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. Numpy 矩阵相关"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# 3.1 随机幺正矩阵\n",
"V = unitary_group.rvs(2) # 随机 2*2 V"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"# 3.2 对角矩阵\n",
"D = np.diag([0.2, 0.8])"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"# 3.3 复共轭\n",
"V_dagger = V.conj().T"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"# 3.4 矩阵乘法:@\n",
"H = (V @ D @ V_dagger)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(0.9999999999999998-8.239936510889834e-18j)"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 3.5 迹\n",
"H.trace()"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([0.2, 0.8])"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 3.6 特征值\n",
"np.linalg.eigh(H)[0]"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"# 3.7 张量积: A \\otimes B\n",
"A = np.eye(2)\n",
"B = H\n",
"T = np.kron(A, B)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 注:在量桨中,可以通过字符串形式构建 $n$ 量子比特泡利矩阵。"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"# 例: 0.4*I⊗Z+0.4*Z⊗I+0.2*X⊗X\n",
"# 文字形式: 0.4*kron(I, Z) + 0.4*kron(Z, I) + 0.2*kron(X, X)\n",
"H_info = [[0.4, 'z0'], [0.4, 'z1'], [0.2, 'x0,x1']]\n",
"H_matrix = pauli_str_to_matrix(H_info, 3) # 3 量子比特泡利矩阵"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4. 量子态相关"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"# 4.1 得到纯态 (np.ndarray 形式的行向量)\n",
"\n",
"initial_state_pure1 = vec(0, N) # 得到 |00…0>, 2**N 维行向量\n",
"initial_state_pure2 = vec_random(N) # 得到随机纯态,行向量"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"# 4.2 得到混态(np.ndarray 形式)\n",
"\n",
"initial_state_mixed1 = density_op(N) # 得到 |00…0><00…0|\n",
"initial_state_mixed2 = density_op_random(N, real_or_complex=2, rank=4) # 得到随机密度矩阵,可选择为实数或复数,可选择秩\n",
"initial_state_mixed3 = completely_mixed_computational(N) # 得到最大混态 "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 5. 量子电路相关"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"# 5.1 创建 N 量子比特电路\n",
"cir = UAnsatz(N)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"# 5.2 添加量子门 —— 具体见第7节\n",
"# 例:添加CNOT门到前两个量子比特\n",
"cir.cnot([0, 1])"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"# 5.3 输出量子态\n",
"# 输出向量形式量子态(paddle.Tensor)。\n",
"# 注:此处输出态shape并不是向量,可通过paddle.reshape(final_state, [2**N, 1])转化为列向量 —— 在后续版本中将进一步优化。\n",
"\n",
"# 初始态为 |00...0>\n",
"final_state = cir.run_state_vector()\n",
"# 初始态非 |00...0>\n",
"initial_state_pure = paddle.to_tensor(initial_state_pure2)\n",
"final_state_pure = cir.run_state_vector(initial_state_pure)\n",
"# 化为 numpy 列向量形式\n",
"final_state_pure_np = cir.run_state_vector().reshape([2**N, 1]).numpy()"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"# 初始态为 |00…0><00…0|\n",
"cir.run_density_matrix()\n",
"# 初始态非 |00...0><00…0|\n",
"initial_state_mixed = paddle.to_tensor(initial_state_mixed2)\n",
"final_state_mixed = cir.run_density_matrix(initial_state_mixed)\n",
"# 改变为 numpy 矩阵形式\n",
"final_state_mixed_np = cir.run_density_matrix().numpy()"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[1., 0., 0., 0., 0., 0., 0., 0.],\n",
" [0., 1., 0., 0., 0., 0., 0., 0.],\n",
" [0., 0., 1., 0., 0., 0., 0., 0.],\n",
" [0., 0., 0., 1., 0., 0., 0., 0.],\n",
" [0., 0., 0., 0., 0., 0., 1., 0.],\n",
" [0., 0., 0., 0., 0., 0., 0., 1.],\n",
" [0., 0., 0., 0., 1., 0., 0., 0.],\n",
" [0., 0., 0., 0., 0., 1., 0., 0.]])"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 5.4 量子电路对应幺正矩阵 (paddle.Tensor)\n",
"cir.U\n",
"# 改变为 numpy 矩阵形式\n",
"cir.U.numpy()\n",
"# 仅保留实数部分\n",
"cir.U.real()\n",
"cir.U.numpy().real"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"--*--\n",
" | \n",
"--x--\n",
" \n",
"-----\n",
" \n"
]
}
],
"source": [
"# 5.5 打印量子电路\n",
"print(cir)"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# 5.6 测量结果\n",
"res = cir.measure(shots=0, plot=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 6. 量子门旋转角参数\n",
"&emsp;注: \n",
"- 单量子比特门总可以由绕轴旋转表示,由旋转轴与旋转角度决定。\n",
"- 量桨中旋转轴通常设置为 $x,y,z$-轴。\n",
"- 旋转角度是量子神经网络的可变参数,**需要设置为 paddle.Tensor 形式**."
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
"# 6.1 单个旋转角度\n",
"\n",
"phi, theta, omega = 2 * np.pi * np.random.uniform(size=3) # 随机旋转角度,服从均匀分布\n",
"# 变为 paddle.Tensor 形式\n",
"phi = paddle.to_tensor(phi, dtype='float64')"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [],
"source": [
"# 6.2 数组形式旋转角度\n",
"# 一维数组\n",
"\n",
"theta = np.array([np.pi, 2 ,3, 5]) # 4个角度均不相同\n",
"theta = np.full([4], np.pi) # 4个角度均等于pi\n",
"# 变为 paddle.Tensor 形式\n",
"phi = paddle.to_tensor(theta)"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [],
"source": [
"# 高维数组\n",
"\n",
"theta = np.random.randn(DEPTH, N, 3) # 一个三维 np.ndarray"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"对于一种常用的量子神经网络: ‘cir.complex_entangled_layer(theta, DEPTH)’,具体见[这里](https://qml.baidu.com/quick-start/quantum-neural-network.html), theta 需要为(DEPTH, N, OTHER=3)形式。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 7. 添加量子门操作"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [],
"source": [
"# 7.1 添加单比特量子门 \n",
"# 注意旋转角度需要 paddle.Tensor 形式。\n",
"# 下标对于旋转轴,第一个参数为旋转角度,第二个参数为作用于第几个量子比特\n",
"\n",
"cir.rz(theta[0], 0)"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [],
"source": [
"# 7.2 添加双量子比特门\n",
"\n",
"cir.cnot([0, 1])"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [],
"source": [
"# 7.3 一些常用的量子门\n",
"\n",
"# 对每一个量子比特添加 Hadamard 门\n",
"cir.superposition_layer()\n",
"# 对每一个量子比特添加 Ry(pi/4) 门\n",
"cir.weak_superposition_layer()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"广义旋转门,基于欧拉角表示,以及对于量子电路具体见[这里](https://qml.baidu.com/quick-start/quantum-neural-network.html)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 8. 变分量子算法基本框架(1)—— 构建量子电路(函数形式)\n",
"- 步骤1:构建 N 量子比特线路\n",
"- 步骤2:对每一层添加量子门"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [],
"source": [
"def circuit(N, DEPTH, theta):\n",
" \"\"\"\n",
" 输入数据:\n",
" N, 量子比特数\n",
" DEPTH, 电路层数\n",
" theta, [N, DEPTH, 2], 3维数组,数据类型:paddle.Tensor\n",
" 返回数据:\n",
" cir, 最终量子电路\n",
" \"\"\"\n",
" # 步骤1:构建N量子比特线路\n",
" cir = UAnsatz(N)\n",
" # 步骤1:对每一层添加量子门\n",
" for dep in range(DEPTH):\n",
" for n in range(N):\n",
" cir.rx(theta[n][dep][0], n) # 对第 n 个量子比特添加 Rx 门\n",
" cir.rz(theta[n][dep][1], n) # 对第 n 个量子比特添加 Rz 门\n",
" for n in range(N - 1):\n",
" cir.cnot([n, n + 1]) # 对每一对临近量子比特添加CNOT门\n",
"\n",
" return cir"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"--Rx(0.069)----Rz(0.473)----*----Rx(-0.65)----Rz(-0.77)-----------------*-------\n",
" | | \n",
"--Rx(-0.77)----Rz(0.623)----x--------*--------Rx(0.428)----Rz(0.074)----x----*--\n",
" | | \n",
"--Rx(-0.45)----Rz(0.604)-------------x--------Rx(2.385)----Rz(-0.12)---------x--\n",
" \n"
]
}
],
"source": [
"# 以下为一个例子,包含3量子比特,两层,可调参数随机产生:\n",
"theta = paddle.to_tensor(np.random.randn(N, DEPTH, 2))\n",
"cir = circuit(N, DEPTH, theta)\n",
"print(cir)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 9. 变分量子算法基本框架(2)—— 设置并计算损失函数\n",
"- 此处我们使用 “-fidelity” 作为损失函数。当输出态为我们想要的量子态时,损失函数达到最小。\n",
"- 注:量子神经网络优化在 Python 中总可以通过迭代器实现,要注意 theta 需要是 paddle.Tensor 形式"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
"class StatePrepNet(paddle.nn.Layer):\n",
" # 步骤1:给出量子神经网络初始值: def __init__(…)\n",
" def __init__(self, N, DEPTH, psi, dtype='float64'):\n",
" # N, DEPTH: 电路参数\n",
" # psi: 目标量子态,数据类型:numpy行向量\n",
" super(StatePrepNet, self).__init__()\n",
" self.N = N\n",
" self.DEPTH = DEPTH\n",
" # 量子电路可调参数初始化随机产生\n",
" self.theta = self.create_parameter(shape=[self.N, self.DEPTH, 2],\n",
" default_initializer=paddle.nn.initializer.Uniform(low=0., high=2 * np.pi), \n",
" dtype=dtype, is_bias=False)\n",
" # 目标量子态,用于计算损失函数(需要 paddle.Tensor 类型)\n",
" self.psi = paddle.to_tensor(psi)\n",
" # 步骤2:计算损失函数L = - <psi_out | psi><psi | psi_out>\n",
" # 注:由于需要最小化损失函数,取“-fidelity”\n",
" def forward(self):\n",
" # 构建量子电路,参数随迭代改变\n",
" cir = circuit(self.N, self.DEPTH, self.theta)\n",
" # 得到此量子电路输出量子态\n",
" psi_out = cir.run_state_vector()\n",
" psi_out = paddle.reshape(psi_out, [2 ** self.N, 1]) # reshape to ket\n",
" # 计算损失函数: L = - <psi_out | psi><psi | psi_out>\n",
" inner = matmul(self.psi, psi_out)\n",
" loss = - paddle.real(matmul(inner, dagger(inner)))[0] # 改变shape为tensor([1])\n",
" \n",
" return loss, cir"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 10. 变分量子算法基本框架(3)—— 通过优化器优化参数\n",
"- 此处我们对制备3量子比特 $|01\\rangle\\otimes|+\\rangle$ 为例,使用的量子电路有上述 “8. 量子神经网络算法基本框架” 部分给出。\n",
"- 通常我们选 Adam 为优化器。\n",
"- 首先我们给出一些训练用的参数。"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [],
"source": [
"N = 3 # 目标量子比特数\n",
"DEPTH = 2 # 量子电路层数\n",
"ITR = 115 # 学习迭代次数\n",
"LR = 0.2 # 学习速率"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [],
"source": [
"# 目标量子态,取 numpy 行向量形式\n",
"psi_target = np.kron(np.kron(np.array([[1,0]]), np.array([[0,1]])), np.array([[1/np.sqrt(2), 1/np.sqrt(2)]])) # <01+|"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [],
"source": [
"# 10.1 记录迭代中间过程\n",
"loss_list = []\n",
"parameter_list = []"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [],
"source": [
"# 10.2 构造迭代器\n",
"# (N=3, DEPTH=2, ITR=110, LR=0.2)\n",
"myLayer = StatePrepNet(N, DEPTH, psi_target)"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [],
"source": [
"# 10.3 选择优化器\n",
"# 通常使用 Adam。\n",
"opt = paddle.optimizer.Adam(learning_rate = LR, parameters = myLayer.parameters()) "
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"iter: 0 loss: -0.0176\n",
"iter: 10 loss: -0.8356\n",
"iter: 20 loss: -0.9503\n",
"iter: 30 loss: -0.9837\n",
"iter: 40 loss: -0.9971\n",
"iter: 50 loss: -0.9974\n",
"iter: 60 loss: -0.9995\n",
"iter: 70 loss: -0.9999\n",
"iter: 80 loss: -0.9999\n",
"iter: 90 loss: -1.0000\n",
"iter: 100 loss: -1.0000\n",
"iter: 110 loss: -1.0000\n"
]
}
],
"source": [
"# 10.4 迭代优化\n",
"for itr in range(ITR):\n",
" # 计算损失函数\n",
" loss = myLayer()[0]\n",
" # 通过梯度下降算法优化\n",
" loss.backward()\n",
" opt.minimize(loss)\n",
" opt.clear_grad()\n",
" # 记录学习曲线\n",
" loss_list.append(loss.numpy()[0])\n",
" parameter_list.append(myLayer.parameters()[0].numpy())\n",
" if itr % 10 == 0:\n",
" print('iter:', itr, ' loss: %.4f' % loss.numpy())"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The minimum of the loss function: -0.9999873168488457\n",
"Parameters after optimizationL theta:\n",
" [[[-0.00816927 7.41571003]\n",
" [ 6.28197865 0.29031951]]\n",
"\n",
" [[ 3.14801248 6.1562368 ]\n",
" [ 6.2890315 4.08082862]]\n",
"\n",
" [[ 4.57489065 1.58064113]\n",
" [ 4.78145659 3.28051687]]]\n",
"--Rx(-0.00)----Rz(7.416)----*----Rx(6.282)----Rz(0.290)-----------------*-------\n",
" | | \n",
"--Rx(3.148)----Rz(6.156)----x--------*--------Rx(6.289)----Rz(4.081)----x----*--\n",
" | | \n",
"--Rx(4.575)----Rz(1.581)-------------x--------Rx(4.781)----Rz(3.281)---------x--\n",
" \n",
"state_final:\n",
" [-0.0001236 +1.65203739e-04j -0.00051346-3.22614883e-04j\n",
" 0.09637039-7.00598643e-01j 0.09558872-7.00513830e-01j\n",
" 0.00038931+1.78566178e-04j 0.0003892 +1.76713800e-04j\n",
" 0.00209719+1.98540264e-03j 0.0025603 +1.33735551e-03j]\n"
]
}
],
"source": [
"# 10.5 输出结果\n",
"\n",
"# 输出最终损失函数值\n",
"print('The minimum of the loss function: ', loss_list[-1])\n",
"# 输出最终量子电路参数\n",
"theta_final = parameter_list[-1] # 得到self.theta\n",
"print(\"Parameters after optimizationL theta:\\n\", theta_final)\n",
"# 绘制最终电路与输出量子态\n",
"# 输入量子电路参数需要转化为 paddle.Tensor 类型\n",
"theta_final = paddle.to_tensor(theta_final)\n",
"# 绘制电路\n",
"cir_final = circuit(N, DEPTH, theta_final)\n",
"print(cir_final)\n",
"# 最终得到量子态\n",
"#state_final = cir_final.run_density_matrix()\n",
"state_final = cir_final.run_state_vector()\n",
"print(\"state_final:\\n\", state_final.numpy())"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYoAAAEGCAYAAAB7DNKzAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Z1A+gAAAACXBIWXMAAAsTAAALEwEAmpwYAAAlFklEQVR4nO3de3hU9b3v8feXJBiBcBWTGJAIaBVBIgbwUhUrWqtu0Wq9HFvBFmm3Z7d216rsYx+LnrabVnu628faHrzi1qIeWovba5W6C1qqBMUb1IJ4C9cAXriIhPA9f/zWQAyTYZLMZDEzn9fz5JnbmjXfycB88rus3zJ3R0REpDVd4i5ARET2bQoKERFJSUEhIiIpKShERCQlBYWIiKRUHHcBmXbAAQd4dXV13GWIiOSURYsWrXf3/skey7ugqK6upq6uLu4yRERyipm929pj6noSEZGUFBQiIpJSrEFhZmeY2ZtmttzMpiZ5fD8zezB6/AUzq46hTBGRghbbGIWZFQG/Bk4D6oGFZvaIuy9pttk3gA/cfaiZXQz8FLio86uVQtfY2Eh9fT3btm2LuxSRDiktLWXAgAGUlJSk/Zw4B7PHAMvdfQWAmT0ATACaB8UEYFp0fTZwq5mZa4Eq6WT19fWUlZVRXV2NmcVdjki7uDsbNmygvr6eQw45JO3nxdn1VAW83+x2fXRf0m3cfQfwEdCv5Y7MbIqZ1ZlZXUNDQ5bKlUK2bds2+vXrp5CQnGZm9OvXr80t47wYzHb3Ge5e6+61/fsnnQYs0mEKCckH7fl3HGdQrAQGNrs9ILov6TZmVgz0AjZkpZpNm+CBB2DFiqzsXkQkV8UZFAuBQ83sEDPrClwMPNJim0eAidH1C4A/Z218oksXmDULnn8+K7sX6agePXpkZb8NDQ2MHTuWo48+mvnz52dsv/fccw+rVq3adXvy5MksWbIkxTPap7q6mvXr17fpOb/97W+59957M/L6zd/XT37yk4zsM6Gzfod75e6x/QBnAv8A3gKuj+67CTgnul4K/D9gOfAiMHhv+zzmmGO83a65xv27323/8yVvLVmyJO4SvHv37lnZ76xZs/wb3/hGxvd78skn+8KFCzO+35YGDRrkDQ0NaW/f2NiYtVra8xnt2LGj1cey9TtM9u8ZqPNWvldjHaNw98fd/TB3H+LuP47uu8HdH4mub3P3r7j7UHcf49EMqaw55hhYvhw++iirLyPSEe7ONddcw/DhwxkxYgQPPvggAKtXr+akk06ipqaG4cOHM3/+fJqampg0adKubX/xi198Zl+LFy/m2muvZc6cOdTU1PDJJ598puUye/ZsJk2aBMCkSZP4zne+w/HHH8/gwYOZPXv2ru1++tOfMmLECEaOHMnUqVOZPXs2dXV1XHrppbv2O27cuF3L68yaNYsRI0YwfPhwrrvuul376dGjB9dffz0jR47k2GOPZe3atXu8/w0bNnD66adz5JFHMnny5MQfnbzzzjsMHz5813a33HIL06ZNA2DcuHF897vfpba2ll/+8pdMmzaNW265Zddj1113HWPGjOGwww7b1araunUrF154IcOGDeO8885j7NixSZcHSryvqVOn8sknn1BTU8Oll14KwH333ceYMWOoqanhm9/8Jk1NTbve59VXX83IkSNZsGABN910E6NHj2b48OFMmTIFd8/q77Ct8m6tpw4ZNQruuw9efhnGjYu7GtlX3X575seyBg+GK65Ia9M//OEPLF68mFdeeYX169czevRoTjrpJH73u9/xxS9+keuvv56mpia2bt3K4sWLWblyJa+//joAH3744Wf2VVNTw0033URdXR233nrrXl979erVPPfcc/z973/nnHPO4YILLuCJJ55gzpw5vPDCC3Tr1o2NGzfSt29fbr31Vm655RZqa2s/s49Vq1Zx3XXXsWjRIvr06cPpp5/OH//4R84991y2bNnCsccey49//GOuvfZabr/9dn7wgx985vk33ngjn//857nhhht47LHHuPPOO9P6vW3fvn3Xl2wiQBJ27NjBiy++yOOPP86NN97IM888w2233UafPn1YsmQJr7/+OjU1NSn3P336dG699VYWL14MwNKlS3nwwQd5/vnnKSkp4corr+T+++/nsssuY8uWLYwdO5af//znAAwbNowbbrgBgK997Ws8+uijXHDBBVn7HbZVXsx6ypihQ6FnT3jppbgrEWnVc889xyWXXEJRURHl5eWcfPLJLFy4kNGjR3P33Xczbdo0XnvtNcrKyhg8eDArVqzg29/+Nk8++SQ9e/bs0Gufe+65dOnShWHDhu36S/WZZ57h8ssvp1u3bgD07ds35T4WLlzIuHHj6N+/P8XFxVx66aXMmzcPgK5du3L22WcDcMwxx/DOO+/s8fx58+bx1a9+FYCzzjqLPn36pFX7RRe1fqzul7/85T1e87nnnuPiiy8GYPjw4Rx11FFpvU7C3LlzWbRoEaNHj6ampoa5c+eyIvoDo6ioiPPPP3/Xts8++yxjx45lxIgR/PnPf+aNN95Iue+O/g7bSi2K5szg6KNDULiH2yItpfmXf2c76aSTmDdvHo899hiTJk3ie9/7HpdddhmvvPIKTz31FL/97W956KGHuOuuu1Lup/n0yZbz7ffbb79d1xNdPplUUlKy6/WLiorYsWNH2s8tLi5m586du263rL179+6tPjfxvtr6mqm4OxMnTuTf//3f93istLSUoqKiXXVeeeWV1NXVMXDgQKZNm9ahFQA68jtsjVoULY0aFcYo3n477kpEkjrxxBN58MEHaWpqoqGhgXnz5jFmzBjeffddysvLueKKK5g8eTIvvfQS69evZ+fOnZx//vn86Ec/4qU0Wsvl5eUsXbqUnTt38vDDD+91+9NOO427776brVu3ArBx40YAysrK2LRp0x7bjxkzhr/85S+sX7+epqYmZs2axcknn5z2+090swE88cQTfPDBB7vqXrduHRs2bODTTz/l0UcfTXufyZxwwgk89NBDACxZsoTXXnttr88pKSmhsbERgFNPPZXZs2ezbt06IPxe3n13z5W8E6FwwAEHsHnz5s+M/WTrd9hWalG0dPTR4XLRotBvLLKPOe+881iwYAEjR47EzPjZz35GRUUFM2fO5Oabb6akpIQePXpw7733snLlSi6//PJdf2kn++u2penTp3P22WfTv39/amtr2bx5c8rtzzjjDBYvXkxtbS1du3blzDPP5Cc/+QmTJk3iW9/6Fvvvvz8LFizYtX1lZSXTp0/nlFNOwd0566yzmDBhQtrv/4c//CGXXHIJRx55JMcffzwHH3wwEL6kb7jhBsaMGUNVVRWHH3542vtM5sorr2TixIkMGzaMww8/nCOPPJJevXqlfM6UKVM46qijGDVqFPfffz8/+tGPOP3009m5cyclJSX8+te/ZtCgQZ95Tu/evbniiisYPnw4FRUVjB49etdj2fodtpVlo/kYp9raWu/wiYuuugq6dYM0/lNJYVi6dClHHHFE3GVIJ2pqaqKxsZHS0lLeeustxo8fz5tvvknXrl3jLq3Dkv17NrNF7l6bbHu1KJIZNQoefhi2bYPS0rirEZEYbN26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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# 绘制迭代过程中损失函数变化曲线\n",
"plt.figure(1)\n",
"ITR_list = []\n",
"for i in range(ITR):\n",
" ITR_list.append(i)\n",
"func = plt.plot(ITR_list, loss_list, alpha=0.7, marker='', linestyle='-', color='r')\n",
"plt.xlabel('iterations')\n",
"plt.ylabel('loss')\n",
"plt.legend(labels=[\"loss function during iteration\"], loc='best')\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**可见,最终 “-fidelity” 变为 “-1”, 此时量子电路已学会如何制备目标量子态 “$|01\\rangle\\otimes|+\\rangle$”。**"
]
}
],
"metadata": {
"interpreter": {
"hash": "b79f688f118b7eec4a7bc67db8fbcf9e8f165bc4247c9c8f9f9067a5de2aa71e"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Frequently Used Functions in Paddle Quantum\n",
"\n",
"<em> Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved. </em>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Overview"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this file, we list some frequently used functions in Paddle Quantum.\n",
"\n",
"You can see other functions in [API](https://qml.baidu.com/api/introduction.html)\n",
"\n",
"Here we will also use preparing a pure state as an example to see how to use Paddle Quantum to realize quantum neural network algorithms."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. Import Mudules "
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"# 1.1 Import numpy and paddle\n",
"import numpy as np\n",
"import paddle\n",
"\n",
"# 1.2 Create quantum circuit\n",
"from paddle_quantum.circuit import UAnsatz \n",
"\n",
"# 1.3 Create quantum state - in np.ndarray form\n",
"from paddle_quantum.state import vec, vec_random # As vector\n",
"from paddle_quantum.state import density_op, density_op_random, completely_mixed_computational # As matrix\n",
"\n",
"# 1.4 Create Matrix - in np.ndarray form\n",
"from scipy.stats import unitary_group # Random U matrix\n",
"from paddle_quantum.utils import pauli_str_to_matrix # Pauli matrices for n qubits\n",
"\n",
"# 1.5 Matrix calculation with paddle.Tensor\n",
"from paddle import matmul, trace # Calculate the inner product and trace\n",
"from paddle_quantum.utils import dagger # Get dagger of a paddle.Tensor (note: for numpy.ndarray, you can use “.conj().T” to do dagger)\n",
"\n",
"# 1.6 Plot figure\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Often Used Parameters"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"# 2.1 Parameters for quantum circuit\n",
"\n",
"N = 3 # Qubits number in Quantum circuit\n",
"DEPTH = 2 # Depth of the quantum circuit (Layers number)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# 2.2 Parameters in the iteration \n",
"\n",
"ITR = 200 # Iteration number \n",
"LR = 0.2 # Learning rate \n",
"SEED = 1 # Random seed \n",
"paddle.seed(SEED) # seed for paddle\n",
"np.random.seed(SEED) # seed for numpy"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. Numpy Matrix"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# 3.1 Random unitary gate\n",
"V = unitary_group.rvs(2) # Random 2*2 V"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"# 3.2 Diagonal matrix\n",
"D = np.diag([0.2, 0.8])"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"# 3.3 Transpose complex conjugate\n",
"V_dagger = V.conj().T"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"# 3.4 Matrix multiplication: @\n",
"H = (V @ D @ V_dagger)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(0.9999999999999998-8.239936510889834e-18j)"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 3.5 Trace\n",
"H.trace()"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([0.2, 0.8])"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 3.6 Eigenvalues\n",
"np.linalg.eigh(H)[0]"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"# 3.7 Tensor product: A \\otimes B\n",
"A = np.eye(2)\n",
"B = H\n",
"T = np.kron(A, B)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Note: in Paddle Quantum, you can use string to create matrix for Pauli matices with $n$ qubit."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"# An example: 0.4*I⊗Z+0.4*Z⊗I+0.2*X⊗X\n",
"# In the string form: 0.4*kron(I, Z) + 0.4*kron(Z, I) + 0.2*kron(X, X)\n",
"H_info = [[0.4, 'z0'], [0.4, 'z1'], [0.2, 'x0,x1']]\n",
"H_matrix = pauli_str_to_matrix(H_info, 3) # pauli matices with 3 qubits"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4. Quantum States"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"# 4.1 Get pure states (a row vector in np.ndarray form)\n",
"\n",
"initial_state_pure1 = vec(0, N) # Get |00…0>, 2**N dimension row vector\n",
"initial_state_pure2 = vec_random(N) # Get random pure state, row vector"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"# 4.2 Get mixed states (in np.ndarray form)\n",
"\n",
"initial_state_mixed1 = density_op(N) # Get |00…0><00…0|\n",
"# Get a random density matrix, can decide real or complex and its rank (rank = 1 means pure) \n",
"initial_state_mixed2 = density_op_random(N, real_or_complex=2, rank=4)\n",
"initial_state_mixed3 = completely_mixed_computational(N) # Get a maximally mixed state "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 5. Quantum Circuit"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"# 5.1 Create an N qubits quantum circuit\n",
"cir = UAnsatz(N)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"# 5.2 Add gates to the circuit - see Section 7\n",
"# An example: add a CNOT gate to the first two qubits:\n",
"cir.cnot([0, 1])"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"# 5.3 The output state of the circuit\n",
"# The output state of the circuit as a vector in paddle.Tensor form.\n",
"# Note: the shape of the output here is not a vector. It can be changed to a column vector \n",
" # via function \"paddle.reshape(final_state, [2**N, 1]) —— it will be made better in the next version\n",
"\n",
"# Initial state is |00...0>\n",
"final_state = cir.run_state_vector()\n",
"# Initial state is not |00...0>\n",
"initial_state_pure = paddle.to_tensor(initial_state_pure2)\n",
"final_state_pure = cir.run_state_vector(initial_state_pure)\n",
"# Change to np.array form\n",
"final_state_pure_np = cir.run_state_vector().reshape([2**N, 1]).numpy()"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"# Initial state is |00…0><00…0|\n",
"cir.run_density_matrix()\n",
"# Initial state is not |00...0><00...0|\n",
"initial_state_mixed = paddle.to_tensor(initial_state_mixed2)\n",
"final_state_mixed = cir.run_density_matrix(initial_state_mixed)\n",
"# Change to np.ndarray form\n",
"final_state_mixed_np = cir.run_density_matrix().numpy()"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[1., 0., 0., 0., 0., 0., 0., 0.],\n",
" [0., 1., 0., 0., 0., 0., 0., 0.],\n",
" [0., 0., 1., 0., 0., 0., 0., 0.],\n",
" [0., 0., 0., 1., 0., 0., 0., 0.],\n",
" [0., 0., 0., 0., 0., 0., 1., 0.],\n",
" [0., 0., 0., 0., 0., 0., 0., 1.],\n",
" [0., 0., 0., 0., 1., 0., 0., 0.],\n",
" [0., 0., 0., 0., 0., 1., 0., 0.]])"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 5.4 The unitary matrix of the circuit (in paddle.Tensor form)\n",
"cir.U\n",
"# Change to np.ndarray form\n",
"cir.U.numpy()\n",
"# Only keep the real part:\n",
"cir.U.real()\n",
"cir.U.numpy().real"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"--*--\n",
" | \n",
"--x--\n",
" \n",
"-----\n",
" \n"
]
}
],
"source": [
"# 5.5 Print the circuit\n",
"print(cir)"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYIAAAEPCAYAAABP1MOPAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Z1A+gAAAACXBIWXMAAAsTAAALEwEAmpwYAAAWB0lEQVR4nO3de7hddX3n8feHm1jBCxKpJYnQGqyoFTVFnjqdooIFawWVKoj1MmicUTrl8dLBqUVL7VRrtZYRqmlV0LYgWouZGsGOSp2xogQUkGAk5SJBrVHESx1R5Dt/rBXY2dn7nJ1j1t4nWe/X85wnZ63f2nt/cv44n7Nuv5WqQpLUX7vNOoAkabYsAknqOYtAknrOIpCknrMIJKnn9ph1gO21//7710EHHTTrGJK0U7niiiu+WVVLRo3tdEVw0EEHsW7dulnHkKSdSpKbx415aEiSes4ikKSeswgkqecsAknqOYtAknrOIpCknuusCJK8O8k3knxxzHiSnJVkY5Krkzy2qyySpPG63CM4FzhmjvFjgRXt1yrgLzvMIkkao7MiqKpPAbfNsclxwHurcRlw/yQP7iqPJGm0Wd5ZfCBwy8Dypnbd14Y3TLKKZq+B5cuXL/gDDzr9Iwt+7Y5w0xt/Y6afL0mj7BQni6tqdVWtrKqVS5aMnCpDkrRAsyyCW4FlA8tL23WSpCmaZRGsAZ7fXj10BPCdqtrmsJAkqVudnSNIcj5wJLB/kk3A64A9AarqHcBa4KnARuAHwIu6yiJJGq+zIqiqk+YZL+DlXX2+JGkyO8XJYklSdywCSeo5i0CSes4ikKSeswgkqecsAknqOYtAknrOIpCknrMIJKnnLAJJ6jmLQJJ6ziKQpJ6zCCSp5ywCSeo5i0CSes4ikKSeswgkqecsAknqOYtAknrOIpCknrMIJKnnLAJJ6jmLQJJ6ziKQpJ6zCCSp5ywCSeo5i0CSes4ikKSeswgkqecsAknqOYtAknrOIpCknuu0CJIck2RDko1JTh8xvjzJJ5N8PsnVSZ7aZR5J0rY6K4IkuwNnA8cChwInJTl0aLPXAhdW1WOAE4FzusojSRqtyz2Cw4GNVXVDVf0IuAA4bmibAu7bfn8/4Ksd5pEkjdBlERwI3DKwvKldN+j1wPOSbALWAr8z6o2SrEqyLsm6zZs3d5FVknpr1ieLTwLOraqlwFOB9yXZJlNVra6qlVW1csmSJVMPKUm7si6L4FZg2cDy0nbdoFOACwGq6jPA3sD+HWaSJA3psgguB1YkOTjJXjQng9cMbfMV4MkASR5OUwQe+5GkKeqsCKrqTuBU4BLgOpqrg65NcmaSp7ebvRJ4SZKrgPOBF1ZVdZVJkrStPbp886paS3MSeHDdGQPfrwee0GUGSdLcZn2yWJI0YxaBJPWcRSBJPWcRSFLPWQSS1HMWgST1nEUgST1nEUhSz1kEktRzFoEk9ZxFIEk9ZxFIUs9ZBJLUcxaBJPWcRSBJPWcRSFLPWQSS1HMWgST1nEUgST1nEUhSz1kEktRzFoEk9ZxFIEk9N1ERJHlCkvu03z8vyVuTPKTbaJKkaZh0j+AvgR8keTTwSuBfgfd2lkqSNDWTFsGdVVXAccDbq+psYN/uYkmSpmWPCbf7XpLXAL8N/GqS3YA9u4slSZqWSfcIngPcAfynqvo6sBR4c2epJElTM1ERtL/8/x64V7vqm8A/dBVKkjQ9k1419BLgg8A721UHAhd1lEmSNEWTHhp6OfAE4LsAVXU98KCuQkmSpmfSIrijqn60ZSHJHkB1E0mSNE2TFsE/J/nvwL2THA18APhf870oyTFJNiTZmOT0Mds8O8n6JNcm+bvJo0uSdoRJLx89HTgFuAZ4KbAW+Ou5XpBkd+Bs4GhgE3B5kjVVtX5gmxXAa4AnVNW3k3i4SZKmbKIiqKq7gL9qvyZ1OLCxqm4ASHIBzQ1p6we2eQlwdlV9u/2cb2zH+0uSdoA5iyDJhVX17CTXMOKcQFX90hwvPxC4ZWB5E/D4oW0OaT/n08DuwOur6uIROVYBqwCWL18+V2RJ0naab4/gd9t/n9bh568AjqS5Se1TSR5VVbcPblRVq4HVACtXrvQktSTtQHOeLK6qr7Xfvqyqbh78Al42z3vfCiwbWF7arhu0CVhTVT+uqhuBL9MUgyRpSia9aujoEeuOnec1lwMrkhycZC/gRGDN0DYX0ewNkGR/mkNFN0yYSZK0A8x3juC/0Pzl//NJrh4Y2hf49Fyvrao7k5wKXEJz/P/dVXVtkjOBdVW1ph17SpL1wE+AV1fVtxb+35Ekba/5zhH8HfBR4E9oLiHd4ntVddt8b15Va2kuNR1cd8bA9wW8ov2SJM3AfEVQVXVTkpcPDyTZb5IykCQtbpPsETwNuILm8tEMjBXw8x3lkiRNyZxFUFVPa/89eDpxJEnTNt/J4sfONV5VV+7YOJKkaZvv0NBb5hgr4Ek7MIskaQbmOzT0xGkFkSTNxnyHhp5UVZ9I8sxR41X1oW5iSZKmZb5DQ78GfAL4zRFjBVgEkrSTm+/Q0Ovaf180nTiSpGmb9OH1D0xyVpIrk1yR5C+SPLDrcJKk7k066dwFwGbgWcAJ7ffv7yqUJGl6Jn1U5YOr6o8Glt+Q5DldBJIkTdekewQfS3Jikt3ar2fTzBwqSdrJzXf56Pe4Z46h04C/aYd2A74PvKrLcJKk7s131dC+0woiSZqNSc8RkOQBNI+R3HvLuqr6VBehJEnTM1ERJHkxzYPslwJfAI4APoNzDUnSTm/Sk8W/C/wycHM7/9BjgNu7CiVJmp5Ji+CHVfVDgCT3qqovAQ/rLpYkaVomPUewKcn9gYuAf0rybeDmrkJJkqZnoiKoqme0374+ySeB+wEXd5ZKkjQ123PV0GOB/0BzX8Gnq+pHnaWSJE3NpJPOnQGcBzwQ2B94T5LXdhlMkjQdk+4RnAw8euCE8RtpLiN9Q0e5JElTMulVQ19l4EYy4F7ArTs+jiRp2uaba+h/0pwT+A5wbZJ/apePBj7XfTxJUtfmOzS0rv33CuAfBtZf2kkaSdLUzTfp3Hlbvk+yF3BIu7ihqn7cZTBJ0nRMOtfQkTRXDd1EMyX1siQvcNI5Sdr5TXrV0FuAp1TVBoAkhwDnA4/rKpgkaTomvWpozy0lAFBVXwb27CaSJGmaJt0juCLJX3PPE8pO5p4TyZKkndikRfCfgZcD/7Vd/j/AOZ0kkiRN1byHhpLsDlxVVW+tqme2X39eVXdM8NpjkmxIsjHJ6XNs96wklWTlduaXJP2U5i2CqvoJsCHJ8u1547ZAzgaOBQ4FTkpy6Ijt9qV58M1nt+f9JUk7xqSHhh5Ac2fx54B/37Kyqp4+x2sOBzZW1Q0ASS4AjgPWD233R8CbgFdPGlqStONMWgR/sID3PhC4ZWB5E/D4wQ3aqa2XVdVHkowtgiSrgFUAy5dv146JJGke8801tDfNieKHAtcA76qqO3fEByfZDXgr8ML5tq2q1cBqgJUrV9aO+HxJUmO+cwTnAStpSuBYmhvLJnUrsGxgeSlbz1i6L/BI4NIkNwFHAGs8YSxJ0zXfoaFDq+pRAEnexfbNOHo5sCLJwTQFcCLw3C2DVfUdmofc0L7/pcCrqsr7EyRpiubbI7h7YrntPSTUbn8qcAlwHXBhVV2b5Mwkc51kliRN0Xx7BI9O8t32+wD3bpcDVFXdd64XV9VaYO3QujPGbHvkRIklSTvUfNNQ7z6tIJKk2Zh00jlJ0i7KIpCknrMIJKnnLAJJ6jmLQJJ6ziKQpJ6zCCSp5ywCSeo5i0CSes4ikKSeswgkqecsAknqOYtAknrOIpCknrMIJKnnLAJJ6jmLQJJ6ziKQpJ6zCCSp5ywCSeo5i0CSes4ikKSeswgkqecsAknqOYtAknrOIpCknrMIJKnnLAJJ6jmLQJJ6ziKQpJ6zCCSp5zotgiTHJNmQZGOS00eMvyLJ+iRXJ/l4kod0mUeStK3OiiDJ7sDZwLHAocBJSQ4d2uzzwMqq+iXgg8CfdpVHkjRal3sEhwMbq+qGqvoRcAFw3OAGVfXJqvpBu3gZsLTDPJKkEbosggOBWwaWN7XrxjkF+OiogSSrkqxLsm7z5s07MKIkaVGcLE7yPGAl8OZR41W1uqpWVtXKJUuWTDecJO3i9ujwvW8Flg0sL23XbSXJUcDvA79WVXd0mEeSNEKXewSXAyuSHJxkL+BEYM3gBkkeA7wTeHpVfaPDLJKkMTorgqq6EzgVuAS4Driwqq5NcmaSp7ebvRnYB/hAki8kWTPm7SRJHeny0BBVtRZYO7TujIHvj+ry8yVJ81sUJ4slSbNjEUhSz1kEktRzFoEk9ZxFIEk9ZxFIUs9ZBJLUcxaBJPWcRSBJPWcRSFLPWQSS1HMWgST1nEUgST1nEUhSz1kEktRzFoEk9ZxFIEk9ZxFIUs9ZBJLUcxaBJPWcRSBJPWcRSFLPWQSS1HMWgST1nEUgST1nEUhSz1kEktRzFoEk9ZxFIEk9ZxFIUs9ZBJLUcxaBJPWcRSBJPddpESQ5JsmGJBuTnD5i/F5J3t+OfzbJQV3mkSRtq7MiSLI7cDZwLHAocFKSQ4c2OwX4dlU9FPhz4E1d5ZEkjdblHsHhwMaquqGqfgRcABw3tM1xwHnt9x8EnpwkHWaSJA3Zo8P3PhC4ZWB5E/D4cdtU1Z1JvgM8EPjm4EZJVgGr2sXvJ9nQSeL57c9Qtu2Rbvd3fqpsHTPbwphtYcw22kPGDXRZBDtMVa0GVs86R5J1VbVy1jlGMdvCmG1hzLYwizVbl4eGbgWWDSwvbdeN3CbJHsD9gG91mEmSNKTLIrgcWJHk4CR7AScCa4a2WQO8oP3+BOATVVUdZpIkDens0FB7zP9U4BJgd+DdVXVtkjOBdVW1BngX8L4kG4HbaMpiMZv54ak5mG1hzLYwZluYRZkt/gEuSf3mncWS1HMWgST1nEUgST1nEUwgyX5J9pt1DknqgkUwRpLlSS5Ishn4LPC5JN9o1x0043iLXpIDkjy2/Tpg1nnmk2SfWWeQZsWrhsZI8hngbcAHq+on7brdgd8CTquqI2YYb6wk11TVo2b4+YcB76C5OXDLDYRLgduBl1XVlbNJNrckX6mq5YsgxwE0U68A3FpV/zbLPPNJsk9VfX/GGUIzt9ndPzfgc4v5nqQkv1hVX5p1ji0sgjGSXF9VK7Z3bBqSPHPcEPCOqloyzTxbBUi+ALy0qj47tP4I4J1V9eiZBGsyvGLcEPD7VTWzw38W6II//ynAOcD1bP1zeyjNz+1js8o2l1n/3IbtFHMNzcgVSc6hmR11y+R5y2juhP78zFI13g/8LTCqxfeecpZh9xkuAYCquizJfWYRaMD/AN4M3DlibNaHSc9lfIG+B1isBTrrQ2p/ARxVVTcNrkxyMLAWePgsQrUZzho3BNx/ilHmZRGM93ya5yX8IVvvcm65I3qWrgb+rKq+ODyQ5KgZ5Bn00SQfAd7L1gX6fODimaVqXAlcVFVXDA8kefEM8gyyQBdmD5qZjYfdCuw55SzDXgS8ErhjxNhJU84yJw8N7YSS/Cpwc1V9ZcTYyqpaN4NYgxmOpXnWxFYFWlVrZ5cKkjwM+FZVbTMNcJIDZnk8vv3r8RcYXaA3VtWpM8z2L8DvjCnQW6pq2YiXTUWS1wDPpnneyeDP7UTgwqr6kxlm+wTw2qr6lxFjN1bVwTOINZJFMEY7G+opwPFs/Qvtw8C7qurHM4qmXdQiL9DbqmrziLGZFmib4eGM/rmtn12q5rJz4IdV9YNZ5piERTBGkvNpTtSdxz27nktpzhHsV1XPmVG0wZJ6BvBz7epFX1JJVlfVqvm3nL7FnE3qmkUwRpIvV9Uh2zs2DYu8pMZdeRPgqqpaOs08WwVY3NnuB7yG5i/bA2guBPgGTbm/sapuXwTZjgcetJiyzSXJR6vq2FnnGGWxZfNk8Xi3Jfkt4O+r6i6AJLvR3Efw7Zkmg8eNKKJNwGVJvjyLQAM2AzfT/HLdotrlB80k0T0Wc7YLgU8AT6yqrwMk+Vnghe3YU2YX7e5sRw5le8GssyV57Lgh4LApRtk2wCLONsw9gjHau4ffBDyR5q9vaC75+iRwelXdOJNgQJLLgLcwuqReUVXDz4aeZrbrgSePOZE96xOLiznbhqp62PaOTcMiz/YT4J/Zuty3OKKq7j3lSHdbzNmGuUcwRlXdlOT1NPcMbHWyeJYl0DqRpqTOTnJ7u+7+NCU164f7vA14ALDNL1vgT6cbZRtvY/FmuznJ7wHnbTn52t5l/ELuuRpmVhZztuto7r+4fnggidkm5B7BGEn+G80v1QvY+o7FE4ELquqNs8oGY6+U+HBVXTe7VI0kv8joqzjMNkaSBwCn02Tbcpjq32juW3ljVc3scOQiz3YCcE1VbRgxdnxVXTT9VHd//qLNNswiGKM91v6I4Stw2ucvXzvjKSYWbUm1fzk+t802eCLbbAuU5EVV9Z5Z5xjFbAuz2LJZBGMk+RLw61V189D6hwAfm/Fx0cVcUmbbwRbbvDSDzLYwiy2b5wjGOw34eHuCccvxvOU0k1nN7C7P1l009w/cPLT+we3YLJltAZJcPW6I5nLSmTHbwizmbMMsgjGq6uIkh7Dt9LaXb5mWeoZOY/GW1GmYbSEOAH6dbS9NDrDNFAVTZraFWczZtmIRzKG9NPOyWecYtphLymwL9o/APlX1heGBJJdOPc3WzLYwiznbVjxHIEk9N+spZCVJM2YRSFLPWQTapSVZmuTDSa5PckOStye51wSvG/kc3iRnbnn4T5LTkvzMmO2eluTzSa5Ksj7JS9v1xyc5dILPn2g7aUewCLTLShLgQzRPJVsBrADuzU8xnURVnVFV/7tdPA3YpgiS7AmsBn6zfUbzY4BL2+HjgUl+wU+6nfRT82SxdllJngy8rqr+48C6+9LcR7AMOAFYueXpX0n+keYRoJe2ewR/RTOz5teBE6tqc5Jzaa4G+Tngz4ANwDer6okDn7Ef8CXgIVX1/wbW/0r72u+0X88CngSsAvYCNgK/TTMz5fB2AGcDS4AfAC+pqi/tkB+Ues89Au3KHgFs9XjFqvoucBPNvQNzuQ+wrqoeQTOD5OuG3ucs4Ks000Y/cWjsNpp5eG5Ocn6Sk5Ps1j6ycA3w6qo6rKr+FfhQVf1yu+dwHXDKmO1W0zwu8nHAq4BztvunIY3hfQTSaHcB72+//xuaQ0wTq6oXJ3kUcBTNL+6jaWbrHPbIJG+gmT12H+CS4Q2S7AP8CvCB5mgXAPOe55AmZRFoV7ae5vDP3dpDQz9Lc0jnkWy9V7z3HO+13cdQq+oa4Jok7wNuZHQRnAscX1VXJXkhcOSIbXYDbq+qw7Y3gzQJDw1pV/Zx4GeSPB8gye40D/R5e3vs/ibgsCS7JVlGc8fxFrtxT4k8F/i/I97/e8C+wyuT7JPkyIFVh3HP/EbDr9kX+Fp7gvnkUe/dHs66sX1iHmk8eq7/uLQ9LALtsqq5EuIZwAnt/ELfAu6qqj9uN/k0zV/q64GzgCsHXv7vwOFJvkhzQvfMER+xGrg4ySeH1gf4vSQbknwB+EPu2Ru4AHh1e2npLwB/AHy2zTJ48nd4u5OBU5JcBVxL82wAaYfwqiH1RnvVzvnAM6rqyvm2l/rCIpCknvPQkCT1nEUgST1nEUhSz1kEktRzFoEk9ZxFIEk99/8BBCQxoFHMDJwAAAAASUVORK5CYII=\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# 5.6 Measure outcome\n",
"res = cir.measure(shots=0, plot=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 6. Angles in Quantum Gate\n",
"&emsp;Note: \n",
"- For qubits unitary gate, they can always be characterized by a rotation axis and a rotation angle. \n",
"- The rotation axis in Paddle Quantum is always chosen to be $x,y,z$-axis.\n",
"- The rotation angle will be the variable in QNN tasks, and **they should be given in paddle.Tensor form**."
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
"# 6.1 A Single Angle\n",
"\n",
"phi, theta, omega = 2 * np.pi * np.random.uniform(size=3) # Generate a random angle\n",
"# change to paddle.Tensor\n",
"phi = paddle.to_tensor(phi, dtype='float64')"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [],
"source": [
"# 6.2 Angles in Arrays\n",
"# 1D arrays\n",
"\n",
"theta = np.array([np.pi, 2 ,3, 5]) # 4 angles are different\n",
"theta = np.full([4], np.pi) # 4 angles all equal to pi\n",
"# change to be paddle.Tensor\n",
"theta = paddle.to_tensor(theta)"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [],
"source": [
"# Multidimensional Arrays\n",
"\n",
"theta = np.random.randn(DEPTH, N, 3) # A 3D np.ndarray"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For a frequently used quantum circuit: cir.complex_entangled_layer(theta, DEPTH), see \n",
"[here](https://qml.baidu.com/quick-start/quantum-neural-network.html), the shape of theta should be(DEPTH, N, OTHER=3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 7. Add Quantum Gates to the Circuit"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [],
"source": [
"# 7.1 Single qubit gates \n",
"# Note: angles should be in paddle.Tensor form.\n",
"# Subscript is the rotating axis, the first parameter is the rotating angle, the second is which qubit it acts\n",
"\n",
"cir.rz(theta[0], 0)"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [],
"source": [
"# # 7.2 Two-qubit gate\n",
"\n",
"cir.cnot([0, 1])"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [],
"source": [
"# 7.3 Some frequently used gates\n",
"\n",
"# Add Hadamard gates to each qubit\n",
"cir.superposition_layer()\n",
"# Add a Ry(pi/4) rotation to each qubit\n",
"cir.weak_superposition_layer()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"General rotation gate in Euler representation, and the corresponding circuit click [here](https://qml.baidu.com/quick-start/quantum-neural-network.html)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 8. VQA basic structure (1) -- Create your own quantum circuit as a function\n",
"- step 1: Create an N qubit circuit;\n",
"- step 2: Add gates to each layer"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [],
"source": [
"def circuit(N, DEPTH, theta):\n",
" \"\"\"\n",
" Input data:\n",
" N, qubits number\n",
" DEPTH, layers number\n",
" theta, [N, DEPTH, 2], 3D matrix in paddle.Tensor form\n",
" Return:\n",
" cir, the final circuit\n",
" \"\"\"\n",
" # step 1: Create an N qubit circuit\n",
" cir = UAnsatz(N)\n",
" # step 2: Add gates to each layer\n",
" for dep in range(DEPTH):\n",
" for n in range(N):\n",
" cir.rx(theta[n][dep][0], n) # add an Rx gate to the n-th qubit\n",
" cir.rz(theta[n][dep][1], n) # add an Rz gate to the n-th qubit\n",
" for n in range(N - 1):\n",
" cir.cnot([n, n + 1]) # add CNOT gate to every neighbor pair\n",
"\n",
" return cir"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"--Rx(0.069)----Rz(0.473)----*----Rx(-0.65)----Rz(-0.77)-----------------*-------\n",
" | | \n",
"--Rx(-0.77)----Rz(0.623)----x--------*--------Rx(0.428)----Rz(0.074)----x----*--\n",
" | | \n",
"--Rx(-0.45)----Rz(0.604)-------------x--------Rx(2.385)----Rz(-0.12)---------x--\n",
" \n"
]
}
],
"source": [
"# Here is the printed final circuit for (N=3, DEPTH=2, theta is randomly generated):\n",
"theta = paddle.to_tensor(np.random.randn(N, DEPTH, 2))\n",
"theta = paddle.to_tensor(theta)\n",
"cir = circuit(N, DEPTH, theta)\n",
"print(cir)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 9. VQA basic structure (2) -- forward part, calculate the loss function\n",
"- QNN optimization can be done with a Python Iterator, here is an example for preparing quantum state;\n",
"- In forward part, all variables should be always in paddle.Tensor form."
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
"class StatePrepNet(paddle.nn.Layer):\n",
" # Step 1: Give the initial input: def __init__(…)\n",
" # Here you need to give the parameters for creating your quantum circuit and loss\n",
" def __init__(self, N, DEPTH, psi, dtype='float64'):\n",
" # N, DEPTH: circuit parameter\n",
" # psi: target output pure state, np.row_vector form\n",
" super(StatePrepNet, self).__init__()\n",
" self.N = N\n",
" self.DEPTH = DEPTH\n",
" # The initial circuit parameter theta is generated randomly\n",
" self.theta = self.create_parameter(shape=[self.N, self.DEPTH, 2],\n",
" default_initializer=paddle.nn.initializer.Uniform(low=0., high=2 * np.pi), \n",
" dtype=dtype, is_bias=False)\n",
" # Target output state, used for loss function\n",
" self.psi = paddle.to_tensor(psi)\n",
" # Step 2: Calculate the loss function: L = - <psi_out | psi><psi | psi_out>\n",
" # note: here we want to minimize the loss function, so we use “-Fidelity”\n",
" def forward(self):\n",
" # Create the quantum circuit\n",
" cir = circuit(self.N, self.DEPTH, self.theta)\n",
" # Get the final state\n",
" psi_out = cir.run_state_vector()\n",
" psi_out = paddle.reshape(psi_out, [2 ** self.N, 1]) # reshape to ket\n",
" # Calculate the loss function: L = - <psi_out | psi><psi | psi_out>\n",
" inner = matmul(self.psi, psi_out)\n",
" loss = - paddle.real(matmul(inner, dagger(inner)))[0] # change to shape tensor([1])\n",
"\n",
" return loss, cir"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 10. VQA basic structure (3) -- backward part, optimize over iteration\n",
"- Here we still use preparing a 3-qubit pure state $|01\\rangle\\otimes|+\\rangle$ as an example, and the circuit we use is given in section 8.\n",
"- Usually we use Adam as the optimizer."
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [],
"source": [
"N = 3 # Qubits number in Quantum circuit\n",
"DEPTH = 2 # Depth of the quantum circuit (Layers number)\n",
"ITR = 115 # Iteration number \n",
"LR = 0.2 # Learning rate "
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [],
"source": [
"# target output state, np.ndarray row vector\n",
"psi_target = np.kron(np.kron(np.array([[1,0]]), np.array([[0,1]])), np.array([[1/np.sqrt(2), 1/np.sqrt(2)]])) # <01+|"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [],
"source": [
"# 10.1 Record the iteration\n",
"loss_list = []\n",
"parameter_list = []"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [],
"source": [
"# 10.2 Use Iterator defined in section 9\n",
"# (N=3, DEPTH=2, ITR=110, LR=0.2)\n",
"myLayer = StatePrepNet(N, DEPTH, psi_target)"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [],
"source": [
"# 10.3 Choose the optimizer\n",
"# Usually we use Adam.\n",
"opt = paddle.optimizer.Adam(learning_rate = LR, parameters = myLayer.parameters()) "
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"iter: 0 loss: -0.0176\n",
"iter: 10 loss: -0.8356\n",
"iter: 20 loss: -0.9503\n",
"iter: 30 loss: -0.9837\n",
"iter: 40 loss: -0.9971\n",
"iter: 50 loss: -0.9974\n",
"iter: 60 loss: -0.9995\n",
"iter: 70 loss: -0.9999\n",
"iter: 80 loss: -0.9999\n",
"iter: 90 loss: -1.0000\n",
"iter: 100 loss: -1.0000\n",
"iter: 110 loss: -1.0000\n"
]
}
],
"source": [
"# 10.4 Optimize during iteration\n",
"for itr in range(ITR):\n",
" # Use forward part to calculate the loss function\n",
" loss = myLayer()[0]\n",
" # Backward optimize via Gradient descent algorithm\n",
" loss.backward()\n",
" opt.minimize(loss)\n",
" opt.clear_grad()\n",
" # Record the learning curve\n",
" loss_list.append(loss.numpy()[0])\n",
" parameter_list.append(myLayer.parameters()[0].numpy())\n",
" if itr % 10 == 0:\n",
" print('iter:', itr, ' loss: %.4f' % loss.numpy())"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The minimum of the loss function: -0.9999873168488457\n",
"Parameters after optimizationL theta:\n",
" [[[-0.00816927 7.41571003]\n",
" [ 6.28197865 0.29031951]]\n",
"\n",
" [[ 3.14801248 6.1562368 ]\n",
" [ 6.2890315 4.08082862]]\n",
"\n",
" [[ 4.57489065 1.58064113]\n",
" [ 4.78145659 3.28051687]]]\n",
"--Rx(-0.00)----Rz(7.416)----*----Rx(6.282)----Rz(0.290)-----------------*-------\n",
" | | \n",
"--Rx(3.148)----Rz(6.156)----x--------*--------Rx(6.289)----Rz(4.081)----x----*--\n",
" | | \n",
"--Rx(4.575)----Rz(1.581)-------------x--------Rx(4.781)----Rz(3.281)---------x--\n",
" \n",
"state_final:\n",
" [-0.0001236 +1.65203739e-04j -0.00051346-3.22614883e-04j\n",
" 0.09637039-7.00598643e-01j 0.09558872-7.00513830e-01j\n",
" 0.00038931+1.78566178e-04j 0.0003892 +1.76713800e-04j\n",
" 0.00209719+1.98540264e-03j 0.0025603 +1.33735551e-03j]\n"
]
}
],
"source": [
"# 10.5 Print the output\n",
"\n",
"print('The minimum of the loss function: ', loss_list[-1])\n",
"# The parameters after optimization\n",
"theta_opt = parameter_list[-1] # Get self.theta\n",
"print(\"Parameters after optimizationL theta:\\n\", theta_opt)\n",
"# Draw the circuit picture and the output state\n",
"# Get theta\n",
"theta_final = parameter_list[-1]\n",
"theta_final = paddle.to_tensor(theta_final)\n",
"# Print the circuit\n",
"cir_final = circuit(N, DEPTH, theta_final)\n",
"print(cir_final)\n",
"# Print the final state\n",
"#state_final = cir_final.run_density_matrix()\n",
"state_final = cir_final.run_state_vector()\n",
"print(\"state_final:\\n\", state_final.numpy())"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYoAAAEGCAYAAAB7DNKzAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Z1A+gAAAACXBIWXMAAAsTAAALEwEAmpwYAAAlFklEQVR4nO3de3hU9b3v8feXJBiBcBWTGJAIaBVBIgbwUhUrWqtu0Wq9HFvBFmm3Z7d216rsYx+LnrabVnu628faHrzi1qIeWovba5W6C1qqBMUb1IJ4C9cAXriIhPA9f/zWQAyTYZLMZDEzn9fz5JnbmjXfycB88rus3zJ3R0REpDVd4i5ARET2bQoKERFJSUEhIiIpKShERCQlBYWIiKRUHHcBmXbAAQd4dXV13GWIiOSURYsWrXf3/skey7ugqK6upq6uLu4yRERyipm929pj6noSEZGUFBQiIpJSrEFhZmeY2ZtmttzMpiZ5fD8zezB6/AUzq46hTBGRghbbGIWZFQG/Bk4D6oGFZvaIuy9pttk3gA/cfaiZXQz8FLio86uVQtfY2Eh9fT3btm2LuxSRDiktLWXAgAGUlJSk/Zw4B7PHAMvdfQWAmT0ATACaB8UEYFp0fTZwq5mZa4Eq6WT19fWUlZVRXV2NmcVdjki7uDsbNmygvr6eQw45JO3nxdn1VAW83+x2fXRf0m3cfQfwEdCv5Y7MbIqZ1ZlZXUNDQ5bKlUK2bds2+vXrp5CQnGZm9OvXr80t47wYzHb3Ge5e6+61/fsnnQYs0mEKCckH7fl3HGdQrAQGNrs9ILov6TZmVgz0AjZkpZpNm+CBB2DFiqzsXkQkV8UZFAuBQ83sEDPrClwMPNJim0eAidH1C4A/Z218oksXmDULnn8+K7sX6agePXpkZb8NDQ2MHTuWo48+mvnz52dsv/fccw+rVq3adXvy5MksWbIkxTPap7q6mvXr17fpOb/97W+59957M/L6zd/XT37yk4zsM6Gzfod75e6x/QBnAv8A3gKuj+67CTgnul4K/D9gOfAiMHhv+zzmmGO83a65xv27323/8yVvLVmyJO4SvHv37lnZ76xZs/wb3/hGxvd78skn+8KFCzO+35YGDRrkDQ0NaW/f2NiYtVra8xnt2LGj1cey9TtM9u8ZqPNWvldjHaNw98fd/TB3H+LuP47uu8HdH4mub3P3r7j7UHcf49EMqaw55hhYvhw++iirLyPSEe7ONddcw/DhwxkxYgQPPvggAKtXr+akk06ipqaG4cOHM3/+fJqampg0adKubX/xi198Zl+LFy/m2muvZc6cOdTU1PDJJ598puUye/ZsJk2aBMCkSZP4zne+w/HHH8/gwYOZPXv2ru1++tOfMmLECEaOHMnUqVOZPXs2dXV1XHrppbv2O27cuF3L68yaNYsRI0YwfPhwrrvuul376dGjB9dffz0jR47k2GOPZe3atXu8/w0bNnD66adz5JFHMnny5MQfnbzzzjsMHz5813a33HIL06ZNA2DcuHF897vfpba2ll/+8pdMmzaNW265Zddj1113HWPGjOGwww7b1araunUrF154IcOGDeO8885j7NixSZcHSryvqVOn8sknn1BTU8Oll14KwH333ceYMWOoqanhm9/8Jk1NTbve59VXX83IkSNZsGABN910E6NHj2b48OFMmTIFd8/q77Ct8m6tpw4ZNQruuw9efhnGjYu7GtlX3X575seyBg+GK65Ia9M//OEPLF68mFdeeYX169czevRoTjrpJH73u9/xxS9+keuvv56mpia2bt3K4sWLWblyJa+//joAH3744Wf2VVNTw0033URdXR233nrrXl979erVPPfcc/z973/nnHPO4YILLuCJJ55gzpw5vPDCC3Tr1o2NGzfSt29fbr31Vm655RZqa2s/s49Vq1Zx3XXXsWjRIvr06cPpp5/OH//4R84991y2bNnCsccey49//GOuvfZabr/9dn7wgx985vk33ngjn//857nhhht47LHHuPPOO9P6vW3fvn3Xl2wiQBJ27NjBiy++yOOPP86NN97IM888w2233UafPn1YsmQJr7/+OjU1NSn3P336dG699VYWL14MwNKlS3nwwQd5/vnnKSkp4corr+T+++/nsssuY8uWLYwdO5af//znAAwbNowbbrgBgK997Ws8+uijXHDBBVn7HbZVXsx6ypihQ6FnT3jppbgrEWnVc889xyWXXEJRURHl5eWcfPLJLFy4kNGjR3P33Xczbdo0XnvtNcrKyhg8eDArVqzg29/+Nk8++SQ9e/bs0Gufe+65dOnShWHDhu36S/WZZ57h8ssvp1u3bgD07ds35T4WLlzIuHHj6N+/P8XFxVx66aXMmzcPgK5du3L22WcDcMwxx/DOO+/s8fx58+bx1a9+FYCzzjqLPn36pFX7RRe1fqzul7/85T1e87nnnuPiiy8GYPjw4Rx11FFpvU7C3LlzWbRoEaNHj6ampoa5c+eyIvoDo6ioiPPPP3/Xts8++yxjx45lxIgR/PnPf+aNN95Iue+O/g7bSi2K5szg6KNDULiH2yItpfmXf2c76aSTmDdvHo899hiTJk3ie9/7HpdddhmvvPIKTz31FL/97W956KGHuOuuu1Lup/n0yZbz7ffbb79d1xNdPplUUlKy6/WLiorYsWNH2s8tLi5m586du263rL179+6tPjfxvtr6mqm4OxMnTuTf//3f93istLSUoqKiXXVeeeWV1NXVMXDgQKZNm9ahFQA68jtsjVoULY0aFcYo3n477kpEkjrxxBN58MEHaWpqoqGhgXnz5jFmzBjeffddysvLueKKK5g8eTIvvfQS69evZ+fOnZx//vn86Ec/4qU0Wsvl5eUsXbqUnTt38vDDD+91+9NOO427776brVu3ArBx40YAysrK2LRp0x7bjxkzhr/85S+sX7+epqYmZs2axcknn5z2+090swE88cQTfPDBB7vqXrduHRs2bODTTz/l0UcfTXufyZxwwgk89NBDACxZsoTXXnttr88pKSmhsbERgFNPPZXZs2ezbt06IPxe3n13z5W8E6FwwAEHsHnz5s+M/WTrd9hWalG0dPTR4XLRotBvLLKPOe+881iwYAEjR47EzPjZz35GRUUFM2fO5Oabb6akpIQePXpw7733snLlSi6//PJdf2kn++u2penTp3P22WfTv39/amtr2bx5c8rtzzjjDBYvXkxtbS1du3blzDPP5Cc/+QmTJk3iW9/6Fvvvvz8LFizYtX1lZSXTp0/nlFNOwd0566yzmDBhQtrv/4c//CGXXHIJRx55JMcffzwHH3wwEL6kb7jhBsaMGUNVVRWHH3542vtM5sorr2TixIkMGzaMww8/nCOPPJJevXqlfM6UKVM46qijGDVqFPfffz8/+tGPOP3009m5cyclJSX8+te/ZtCgQZ95Tu/evbniiisYPnw4FRUVjB49etdj2fodtpVlo/kYp9raWu/wiYuuugq6dYM0/lNJYVi6dClHHHFE3GVIJ2pqaqKxsZHS0lLeeustxo8fz5tvvknXrl3jLq3Dkv17NrNF7l6bbHu1KJIZNQoefhi2bYPS0rirEZEYbN26lVNOOYXGxkbcndtuuy0vQqI9FBTJHH44NDXBO++E6yJScMrKynRa5YgGs5Oprg6XSQaepHDlWzetFKb2/DtWUCRz4IGhy0lBIZHS0lI2bNigsJCc5tH5KErb2KWurqdkzGDQoND1JAIMGDCA+vp6dL4TyXWJM9y1hYKiNYMGwYIFOvBOgDD1si1nBBPJJ+p6as2gQeEcFS3WxhERKTQKitZoQFtEBFBQtC5x9KSCQkQKnIKiNb16hR8NaItIgVNQpFJdrRaFiBQ8BUUqgwbBe++FmU8iIgVKQZFKdTV8+imsWRN3JSIisVFQpKIBbRERBUVK0Tr3GtAWkUKmoEiltBQqKtSiEJGCpqDYm4EDob4+7ipERGKjoNibigpYu1Yzn0SkYCko9qa8HD75BPZy3mARkXyloNib8vJwqSmyIlKgFBR7kwiKtWvjrUNEJCYKir1Ri0JECpyCYm+6dYOyMrUoRKRgKSjSkZj5JCJSgBQU6SgvV1CISMGKJSjMrK+ZPW1my6LLPkm2qTGzBWb2hpm9amYXxVErEIJi3TrYuTO2EkRE4hJXi2IqMNfdDwXmRrdb2gpc5u5HAmcA/2FmvTuvxGbKy2HHDti4MZaXFxGJU1xBMQGYGV2fCZzbcgN3/4e7L4uurwLWAf07q8DPqKgIl5r5JCIFKK6gKHf31dH1NUB5qo3NbAzQFXirlcenmFmdmdU1NDRktlLQsRQiUtCKs7VjM3sGqEjy0PXNb7i7m1mrCymZWSXwn8BEd086SODuM4AZALW1tZlflKl/fzBTUIhIQcpaULj7+NYeM7O1Zlbp7qujIFjXynY9gceA6939b1kqde9KSqBfP3U9iUhBiqvr6RFgYnR9IjCn5QZm1hV4GLjX3Wd3Ym3JaYqsiBSouIJiOnCamS0Dxke3MbNaM7sj2uZC4CRgkpktjn5qYqkWdNCdiBSsrHU9peLuG4BTk9xfB0yOrt8H3NfJpbWuvDxMj21sDF1RIiIFQkdmp6u8PJy8aF3S4RQRkbyloEiXVpEVkQKloEhX4qA7jVOISIFRUKSrb98wNqEWhYgUGAVFusw0RVZECpKCoi0qKtSiEJGCo6Boi4oKWL06zH4SESkQCoq2qKiATz6BTZvirkREpNMoKNpCy42LSAFSULSFgkJECpCCoi100J2IFCAFRVuUlkKfPgoKESkoCoq20hRZESkwCoq2SkyRFREpEAqKtqqogA0bwnLjIiIFQEHRVhUVWm5cRAqKgqKtNEVWRAqMgqKtFBQiUmAUFG3Vpw907aqgEJGCoaBoq8Ry4woKESkQCor20LEUIlJAFBTtkQgKLTcuIgVAQdEelZWwbRt88EHclYiIZJ2Coj2qq8Pl22/HWoaISGdQULTH4MHh8q234q1DRKQTKCjao3v30P2koBCRAqCgaK8hQ2D58rirEBHJOgVFew0ZEtZ70vmzRSTPKSjaa+jQcLliRbx1iIhkmYKivYYMCZfqfhKRPKegaK+yMjjwQA1oi0jeiyUozKyvmT1tZsuiyz4ptu1pZvVmdmtn1piWIUMUFCKS9+JqUUwF5rr7ocDc6HZr/jcwr1OqaqshQ2DVKti6Ne5KRESyJq6gmADMjK7PBM5NtpGZHQOUA3/qnLLaKDFOoQFtEcljcQVFubuvjq6vIYTBZ5hZF+DnwPf3tjMzm2JmdWZW19DQkNlKU0nMfFL3k4jkseJs7djMngEqkjx0ffMb7u5mlmwZ1iuBx9293sxSvpa7zwBmANTW1nbekq69e0PfvgoKEclrWQsKdx/f2mNmttbMKt19tZlVAuuSbHYccKKZXQn0ALqa2WZ3TzWe0fl0hLaI5Lm4up4eASZG1ycCc1pu4O6XuvvB7l5N6H66d58LCQhBUV8Pn34adyUiIlkRV1BMB04zs2XA+Og2ZlZrZnfEVFP7DB0aTmD0zjtxVyIikhVZ63pKxd03AKcmub8OmJzk/nuAe7JeWHskZj699RZ87nPx1iIikgU6Mruj+vWDnj01TiEieUtB0VFm4URGmvkkInlKQZEJQ4fCe+/Bjh1xVyIiknEKikwYMiSExHvvxV2JiEjGKSgyofmAtohInlFQZEJFBXTrpgFtEclLCopM0IC2iOQxBUWmDBkCb78NO3fGXYmISEYpKDJlyBDYvh1Wroy7EhGRjFJQZIrOoS0ieSqtoDCzq6JTkpqZ3WlmL5nZ6dkuLqdUVUFxMbz/ftyViIhkVLotiq+7+8fA6UAf4GtEC/lJpKgozH5S15OI5Jl0gyJx5qAzgf909zea3ScJVVUKChHJO+kGxSIz+xMhKJ4yszJA03taqqqCVas080lE8kq6y4x/A6gBVrj7VjPrC1yetapyVVUVNDbC+vVw4IFxVyMikhHptiiOA9509w/N7KvAD4CPsldWjjrooHBZXx9vHSIiGZRuUPwG2GpmI4GrgbeAe7NWVa4aMCBcapxCRPJIukGxw90dmADc6u6/BsqyV1aO6tUrrPmkoBCRPJLuGMUmM/s3wrTYE82sC1CSvbJylJlmPolI3km3RXER8CnheIo1wADg5qxVlcsUFCKSZ9IKiigc7gd6mdnZwDZ31xhFMlVV0NAQ1n0SEckD6S7hcSHwIvAV4ELgBTO7IJuF5ayqqnC5alW8dYiIZEi6YxTXA6PdfR2AmfUHngFmZ6uwnJUIipUrobo61lJERDIh3TGKLomQiGxow3MLS+JYCo1TiEieSLdF8aSZPQXMim5fBDyenZJyXGkp9OunoBCRvJFWULj7NWZ2PnBCdNcMd384e2XlOM18EpE8km6LAnf/PfD7LNaSP6qqYP58cA/HVoiI5LCUQWFmmwBP9hDg7t4zK1Xluqoq2LwZPv44HK0tIpLDUgaFu2uZjvZIDGivWaOgEJGcp5lL2VBZGS51LIWI5AEFRTaUl4exidWr465ERKTDYgkKM+trZk+b2bLosk8r2x1sZn8ys6VmtsTMqju51PYpKYH+/RUUIpIX4mpRTAXmuvuhwNzodjL3Aje7+xHAGGBdK9vteyorFRQikhfiCooJwMzo+kzg3JYbmNkwoNjdnwZw983uvrXTKuyoykqNUYhIXogrKMrdPfHn9hqgPMk2hwEfmtkfzOxlM7vZzIqS7czMpphZnZnVNTQ0ZKvmtjnoINi0CbZsibsSEZEOyVpQmNkzZvZ6kp8JzbeLzpyX7FiNYuBE4PvAaGAwMCnZa7n7DHevdffa/v37Z/aNtFdi5pO6n0Qkx6V9ZHZbufv41h4zs7VmVunuq82skuRjD/XAYndfET3nj8CxwJ3ZqDfjmgfF0KHx1iIi0gFxdT09AkyMrk8E5iTZZiHQO1rSHOALwJJOqC0zKirCpVoUIpLj4gqK6cBpZrYMGB/dxsxqzewOAHdvInQ7zTWz1wjLhtweU71tt99+0LevBrRFJOdlrespFXffAJya5P46YHKz208DR3ViaZl10EFqUYhIztOR2dmkYylEJA8oKLKpshI++AC2bYu7EhGRdlNQZJOmyIpIHlBQZFNiuXEFhYjkMAVFNmmKrIjkAQVFNnXrFk5cpKAQkRymoMg2LQ4oIjlOQZFtVVWwcmXcVYiItJuCItsOOgg2btQUWRHJWQqKbBswIFyqVSEiOUpBkW1VVeFSQSEiOUpBkW2VlWAG9fVxVyIi0i4Kimzr2hUOPFAtChHJWQqKzqCZTyKSwxQUnSERFJ7sjK8iIvs2BUVnGDAgTI/duDHuSkRE2kxB0Rk080lEcpiCojMoKEQkhykoOkO/fuEc2goKEclBCorOYBZaFTqWQkRykIKis2iKrIjkKAVFZ6mqgrVrobEx7kpERNpEQdFZBgwIx1GsWRN3JSIibaKg6CyJ82drnEJEcoyCorNouXERyVEKis6y//7Qt69aFCKScxQUnWnAALUoRCTnKCg6U+JYCi0OKCI5REHRmaqqYPNm+PjjuCsREUmbgqIzaUBbRHKQgqIzJRYH1IC2iOQQBUVnOvBAKClRUIhIToklKMysr5k9bWbLoss+rWz3MzN7w8yWmtmvzMw6u9aM6tIlHHinricRySFxtSimAnPd/VBgbnT7M8zseOAE4ChgODAaOLkzi8wKLQ4oIjkmrqCYAMyMrs8Ezk2yjQOlQFdgP6AEWNsZxWXVgAGwejXs2BF3JSIiaYkrKMrdfXV0fQ1Q3nIDd18APAusjn6ecvelyXZmZlPMrM7M6hoaGrJVc2ZUVcHOnVocUERyRtaCwsyeMbPXk/xMaL6duzuh9dDy+UOBI4ABQBXwBTM7MdlrufsMd69199r+/ftn4d1kkKbIikiOKc7Wjt19fGuPmdlaM6t099VmVgmsS7LZecDf3H1z9JwngOOA+VkpuLM0nyI7dmy8tYiIpCGurqdHgInR9YnAnCTbvAecbGbFZlZCGMhO2vWUU7p3h969NUVWRHJGXEExHTjNzJYB46PbmFmtmd0RbTMbeAt4DXgFeMXd/yuOYjNOiwOKSA7JWtdTKu6+ATg1yf11wOToehPwzU4urXNUVcFf/xp3FSIiadGR2XEYMAA2bdLigCKSExQUcUjMfNI4hYjkAAVFHA4+OFy+9168dYiIpEFBEYf+/WG//dSiEJGcoKCIg1noflKLQkRygIIiLgcfDO+/H3cVIiJ7Fcv0WCG0KJ59Fj75BPbfv23PXboUbrsNmprC+S3GjIFLL81OnSJS8NSiiEtiQLut4xQ7dsCvfhWm1g4aBF27wgMPwIIFma9RRAS1KOIzcGC4fO89OPTQ9J/3X/8VwuWGG2D06BAcV18dWhjDh0NZWXbqFZGCpRZFXCoqoLi4bS2KjRvhd78LATF6dLivuBiuuiocwDdjRnZqFZGCpqCIS1FROC1qW2Y+3XNPaEFcccVn7x88GC66CP77v2HhwkxWKSKioIhVW2Y+rVsXBr/PPRcqK/d8/CtfgfJy+P3vM1qiiIiCIk4DB4Yz3W3fvvdt50en4fjiF5M/XlwMZ50Fb7wB77yTsRJFRBQUcRo4ENxh1aq9bzt/fhj0rqhofZvx48MsqMcey1yNIlLwFBRxaj7zKZXVq+Gtt+DEpGeC3a2sDE4+OXRRbdmSmRpFpOApKOJUVRWW89jbOEWi22lvQQGh++nTT2Hu3I7XJyKCgiJeJSVhYDqdoDjiCDjggL3vc8gQOPzw0P3knpk6RaSgKSjiVl0Ny5a1/qVeXx8Gpz//+fT3edZZYdzjlVcyUaGIFDgFRdxGjgxTX1sb0H7uudA91ZagOOEE6NkTnngiMzWKSEFTUMRt1Khw+dJLez7mHg6iO/JI6Ns3/X2WlIQZUH/7WziaW0SkAxQUcauoCOMUL7+852NvvgkrV8Kpp7Z9v2ecATt3wtNPd7xGESloCop9wahR8Oqr0Nj42fvnzg1nwjvhhLbvs7ISamrgySdDYIiItJOCYl8walSY0rp06e77tm8Ps52OP77t56tI+NKXYP16WLQoM3WKSEFSUOwLRowIiwQ273564YVw0Fx7up0SxowJYxuPPtrxGkWkYCko9gX77x+Ok2g+oD13bjhu4qij2r/f4mL4p38K+3399Y7XKSIFSUGxrxg1ClasCF1Ff/97+HL/whfC1NiOOOecEDh33aUD8ESkXRQU+4rENNmvfx2uuWb3FNeO6toVvva1cFBfYikQEZE20KlQ9xWDB8OECdClCwwdGrqi+vfPzL5POQXmzIGZM+HYY0N4iIikSUGxrzCDyZOzt++vfx1+8AO4/Xb4538OgdRWW7bAhx/C1q3hTHsHHQS9emW8XBHZtygoCsXIkXD++eEMeB9/DFdfvfeWhTssXw4vvhjGTJKtSdWzZ2gNHXVUeI2hQ9sXQiKyz1JQFJJJk6B3b7jzTvjgAzj77PDlnmgVuId1p5YvhyVL4K9/DYPrZvC5z8HFF4dWRLduIQxWrgzn0njzTbj33rCPsjI4+mg45pgw7tK7d0xvVkQyxTyGmTBm9hVgGnAEMMbd61rZ7gzgl0ARcIe7T9/bvmtra72uLunuJGHePPjNb2Dz5nC7V6/QlbR9++6jw0tKwhf+8ceH4zHKylLv88MPw9HlixaFn48+CvcPHRr2c8QRYfnzve1HRGJhZovcvTbpYzEFxRHATuD/At9PFhRmVgT8AzgNqAcWApe4+5JU+1ZQpKmpKZw1b/FiaGgIwVBcHFoMQ4bAoEHtH/R2D1N9Fy2Cujr4xz/C60EIit69w+WOHeGI9E8+CeMeW7eG5xYVhVp69AjbNf/p0SMcd9KtG3TvHi733z8sdVJaGp6X6PrasSMEX2NjeJ3t28Nl4mfbtt3Xm5rC9l26hH2UlOz5Gt26hdfo2jW8XnHx7lqLisJzU01nNtv9I7KPSRUUsXQ9uftSAEv9H2YMsNzdV0TbPgBMAFIGhaSpqAgOOyz8ZJpZCJshQ+DCC8MX8bJl4fiQhobQ7bVpU/jS79cvfPkmvpC7dAlf2o2NocWzaVMYU3n33XB9y5bwhZ5JRUUhGIqKwrpYiYDJJrPdwdKlS/hJhE0ieBI/iXBJ/FHnvvsnsY5X4naq12seUi0Dq+Xtlvvb2x+ULf8vd0Ygtqy/LX/0tty2rb+/ZPtorbZk2zXfV3v/WE/2+62uhmuvbd/+UtiXxyiqgOanfqsHxibb0MymAFMADj744OxXJm2z334wfHj4yYTGxt0tkMRPonXQ1LT7yzPRMigpCa2AREsg8VNaGi6LivZ8DffdLZ0tW8L1LVt2t0y2bw+BsmNHeM3E6zb/Mk/2ZZH4ck/UmLi+c+fu/SRaN4n7mi/q2PwLK9Fyan5fa6+ZeK3mj7V8vGXNiX03f41kku0n2eMtpRskyZ6fiZ6QlkGT7BI++1kl20eqgE32WpnuxWn+uVVWZnbfkawFhZk9A1Qkeeh6d5+Tyddy9xnADAhdT5nct+yDSkrCuEo2p+aahRZOt27pnYJWJI9lLSjcvaOHFa8EBja7PSC6T0REOtG+POF9IXComR1iZl2Bi4FHYq5JRKTgxBIUZnaemdUDxwGPmdlT0f0HmdnjAO6+A/gX4ClgKfCQu78RR70iIoUsrllPDwMPJ7l/FXBms9uPA493YmkiItLCvtz1JCIi+wAFhYiIpKSgEBGRlBQUIiKSUixrPWWTmTUA73ZgFwcA6zNUzr5C7yl35OP7ysf3BPn3vga5e9KzpeVdUHSUmdW1tjBWrtJ7yh35+L7y8T1B/r6vZNT1JCIiKSkoREQkJQXFnmbEXUAW6D3ljnx8X/n4niB/39ceNEYhIiIpqUUhIiIpKShERCQlBUXEzM4wszfNbLmZTY27nvYys4Fm9qyZLTGzN8zsquj+vmb2tJktiy77xF1rW5lZkZm9bGaPRrcPMbMXos/swWg5+pxhZr3NbLaZ/d3MlprZcXnyOf1r9G/vdTObZWalufZZmdldZrbOzF5vdl/Sz8aCX0Xv7VUzGxVf5dmhoCB8AQG/Br4EDAMuMbNh8VbVbjuAq919GHAs8D+j9zIVmOvuhwJzo9u55irCkvMJPwV+4e5DgQ+Ab8RSVfv9EnjS3Q8HRhLeW05/TmZWBXwHqHX34UAR4VwyufZZ3QOc0eK+1j6bLwGHRj9TgN90Uo2dRkERjAGWu/sKd98OPABMiLmmdnH31e7+UnR9E+HLp4rwfmZGm80Ezo2lwHYyswHAWcAd0W0DvgDMjjbJqfdkZr2Ak4A7Adx9u7t/SI5/TpFiYH8zKwa6AavJsc/K3ecBG1vc3dpnMwG414O/Ab3NLDsnr46JgiKoAt5vdrs+ui+nmVk1cDTwAlDu7qujh9YA5XHV1U7/AVwLJM5w3w/4MDrBFeTeZ3YI0ADcHXWn3WFm3cnxz8ndVwK3AO8RAuIjYBG5/VkltPbZ5OX3R3MKijxlZj2A3wPfdfePmz/mYU50zsyLNrOzgXXuvijuWjKoGBgF/Mbdjwa20KKbKdc+J4Co334CIQgPArqzZxdOzsvFz6YjFBTBSmBgs9sDovtykpmVEELifnf/Q3T32kRzOLpcF1d97XACcI6ZvUPoFvwCoX+/d9S9Abn3mdUD9e7+QnR7NiE4cvlzAhgPvO3uDe7eCPyB8Pnl8meV0Npnk1ffH8koKIKFwKHRzIyuhMG3R2KuqV2ivvs7gaXu/n+aPfQIMDG6PhGY09m1tZe7/5u7D3D3asJn82d3vxR4Frgg2izX3tMa4H0z+1x016nAEnL4c4q8BxxrZt2if4uJ95Wzn1UzrX02jwCXRbOfjgU+atZFlRd0ZHbEzM4k9IMXAXe5+4/jrah9zOzzwHzgNXb35/8vwjjFQ8DBhGXYL3T3loN1+zwzGwd8393PNrPBhBZGX+Bl4Kvu/mmM5bWJmdUQBue7AiuAywl/vOX052RmNwIXEWbgvQxMJvTZ58xnZWazgHGEpcTXAj8E/kiSzyYKxFsJXWxbgcvdvS6GsrNGQSEiIimp60lERFJSUIiISEoKChERSUlBISIiKSkoREQkJQWFSAtm9tfostrM/keG9/2/kr2WyL5M02NFWtH8mI02PKe42ZpGyR7f7O49MlCeSKdRi0KkBTPbHF2dDpxoZoujcywUmdnNZrYwOu/AN6Ptx5nZfDN7hHAUMmb2RzNbFJ2XYUp033TCqqqLzez+5q8VHdV7c3QOh9fM7KJm+/7vZuetuD86wAszm27hvCOvmtktnfk7ksJSvPdNRArWVJq1KKIv/I/cfbSZ7Qc8b2Z/irYdBQx397ej21+PjtrdH1hoZr9396lm9i/uXpPktb4M1BDOS3FA9Jx50WNHA0cCq4DngRPMbClwHnC4u7uZ9c7sWxfZTS0KkfSdTljTZzFhSZR+hJPVALzYLCQAvmNmrwB/IywYdyipfR6Y5e5N7r4W+Aswutm+6919J7AYqCYs370NuNPMvkxYOkIkKxQUIukz4NvuXhP9HOLuiRbFll0bhbGN8cBx7j6SsLZRaQdet/maSE1AYhxkDGHV2bOBJzuwf5GUFBQirdsElDW7/RTwz9Ey7pjZYdHJhlrqBXzg7lvN7HDCKWkTGhPPb2E+cFE0DtKfcPa7F1srLDrfSC93fxz4V0KXlUhWaIxCpHWvAk1RF9I9hHNgVAMvRQPKDSQ/peeTwLeicYQ3Cd1PCTOAV83spWip9ISHgeOAVwgnxLnW3ddEQZNMGTDHzEoJLZ3vtesdiqRB02NFRCQldT2JiEhKCgoREUlJQSEiIikpKEREJCUFhYiIpKSgEBGRlBQUIiKS0v8HaZuxI0AZydEAAAAASUVORK5CYII=\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# Print the loss function during iteration\n",
"plt.figure(1)\n",
"ITR_list = []\n",
"for i in range(ITR):\n",
" ITR_list.append(i)\n",
"func = plt.plot(ITR_list, loss_list, alpha=0.7, marker='', linestyle='-', color='r')\n",
"plt.xlabel('iterations')\n",
"plt.ylabel('loss')\n",
"plt.legend(labels=[\"loss function during iteration\"], loc='best')\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**As the \"-Fidelity\" becomes \"-1\", this circuit learns to prepare the target state \"$|01\\rangle\\otimes|+\\rangle$\".**"
]
}
],
"metadata": {
"interpreter": {
"hash": "b79f688f118b7eec4a7bc67db8fbcf9e8f165bc4247c9c8f9f9067a5de2aa71e"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
...@@ -137,7 +137,11 @@ ...@@ -137,7 +137,11 @@
"source": [ "source": [
"我们可以在命令行中输入`nvidia-smi`来查看 GPU 的使用情况,包括有哪些程序在哪些 GPU 上运行,以及其显存占用情况。\n", "我们可以在命令行中输入`nvidia-smi`来查看 GPU 的使用情况,包括有哪些程序在哪些 GPU 上运行,以及其显存占用情况。\n",
"\n", "\n",
"这里,我们以 [VQE](../tutorial/quantum_simulation/VQE_CN.ipynb) 为例来说明我们该如何使用 GPU。首先,导入相关的包并定义相关的变量和函数。" "这里我们以变分量子本征求解器(Variational Quantum Eigensolver, [VQE](/tutorials/quantum-simulation/variational-quantum-eigensolver.html) )为例来说明我们该如何使用GPU。简单来说,它利用参数化的电路搜寻广阔的希尔伯特空间,并利用经典机器学习中的梯度下降来找到最优参数,并接近一个哈密顿量(Hamiltonian)的基态(也就是找到一个埃尔米特矩阵的最小本征值)。此处哈密顿量由以下 H2_generator() 函数给出,使用的量子神经网络架构如下图所示:\n",
"\n",
"![circuit](./figures/gpu-fig-circuit.jpg)\n",
"\n",
"首先,导入相关的包并定义相关的变量和函数:"
] ]
}, },
{ {
...@@ -398,7 +402,7 @@ ...@@ -398,7 +402,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.8.3" "version": "3.7.10"
}, },
"toc": { "toc": {
"base_numbering": 1, "base_numbering": 1,
......
...@@ -142,7 +142,12 @@ ...@@ -142,7 +142,12 @@
"source": [ "source": [
"We can enter `nvidia-smi` in the command line to view the usage of the GPU, including which programs are running on which GPUs, and its memory usage.\n", "We can enter `nvidia-smi` in the command line to view the usage of the GPU, including which programs are running on which GPUs, and its memory usage.\n",
"\n", "\n",
"Here, we take [VQE](../tutorial/quantum_simulation/VQE_EN.ipynb) as an example to illustrate how we should use GPU. First, import the related packages and define some variables and functions." "Here, we take Variational Quantum Eigensolver ([VQE](/tutorials/quantum-simulation/variational-quantum-eigensolver.html)) as an example to illustrate how we should use GPU. \n",
"For simplicity, VQA use a parameterized quantum circuit to search the vast Hilbert space, and uses the gradient descent method to find the optimal parameters, to get close to the ground state of a Hamiltonian (the smallest eigenvalue of the Hermitian matrix). The Hamiltonian in our example is given by the following H2_generator() function, and the quantum neural network has the following structure:\n",
"\n",
"![circuit](./figures/gpu-fig-circuit.jpg)\n",
"\n",
"First, import the related packages and define some variables and functions:"
] ]
}, },
{ {
...@@ -405,7 +410,7 @@ ...@@ -405,7 +410,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.8.3" "version": "3.7.10"
}, },
"toc": { "toc": {
"base_numbering": 1, "base_numbering": 1,
......
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 利用 Paddle Quantum 的 qchem 模块进行量子化学计算\n",
"_Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved._\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"qchem 是基于 Paddle Quantum 推出的用于量子化学研究的工具集。qchem 为量子化学领域的研究者提供了一系列工具,使他们可以利用量子计算方法完成量子化学任务。与此同时,qchem 也提供了方便开发者进行功能拓展的方式。目前,qchem 正处于开发之中,您可以将需求和建议通过 Github 的 issue 或 pull request 反馈给我们,我们会及时给出回复。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 分子基态能量计算\n",
"qchem 提供了 `run_chem` 函数来计算给定分子的基态能量和基态波函数。让我们通过计算氢分子基态能量的例子来了解一下整个计算过程。首先,让我们导入需要用的函数。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from paddle_quantum import qchem"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"接下来,让我们把与计算相关的信息输入到 `run_chem` 函数中,这些信息包括:分子的几何结构、分子的电荷、计算需要用到的量子化学基函数等。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# define the geometry of hydrogen molecule, length unit use angstrom.\n",
"h2_geometry = [(\"H\", [0.0, 0.0, 0.0]), (\"H\", [0.0, 0.0, 0.74])]\n",
"charge = 0\n",
"basis_set = \"sto-3g\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"现在,我们需要选择一种多体波函数的量子线路模版来作为基态能量计算中的变分波函数。目前,qchem 提供了两种模式,分别是 \"hardware efficient\" [<sup>1</sup>](#refer-1) 和 \"hartree fock\" [<sup>2</sup>](#refer-2) ,更多的模式正在开发中,很快也会上线。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# call run_chem function with \"hardware efficient\" ansatz.\n",
"h2_gs_en, h2_wf_model = qchem.run_chem(\n",
" h2_geometry,\n",
" \"hardware efficient\",\n",
" basis_set, \n",
" charge\n",
")\n",
"\n",
"# additional information for optimizer can be passed using `optimizer_option` keyword argument.\n",
"h2_gs_en, h2_wf_model = qchem.run_chem(\n",
" h2_geometry,\n",
" \"hardware efficient\",\n",
" basis_set, \n",
" charge,\n",
" optimizer_option={\"learning_rate\": 0.6, \"weight_decay\": 0.9}\n",
")\n",
"\n",
"# additional information for ansatz can be passed using `ansatz_option` keyword argument, e.g.\n",
"# \"hardware efficient\" ansatz has a parameter \"cir_depth\", which can be used to specify the depth\n",
"# of quantum circuit.\n",
"h2_gs_en, h2_wf_model = qchem.run_chem(\n",
" h2_geometry,\n",
" \"hardware efficient\",\n",
" basis_set, \n",
" charge,\n",
" ansatz_option={\"cir_depth\": 5}\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"除了上面这些参数,我们也可以通过给定 `max_iters` 和 `a_tol` 来控制训练过程的迭代次数和收敛条件。如果想使用 \"hartree fock\" 量子线路,我们只需要把上面代码中的 \"hardware efficient\" 替换为 \"hartree fock\" 就可以了。我们也可以通过 `print(h2_wf_model.circuit)` 的方法来查看氢分子波函数的量子线路。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 自定义量子线路\n",
"在 qchem 中,我们也为感兴趣的使用者提供了自定义量子线路的方法。我们只需要继承 qchem 中的 Qmodel 类就可以像在 paddlepaddle 中定义神经网络一样定义波函数对应的量子线路。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from paddle_quantum.circuit import UAnsatz\n",
"from paddle_quantum import qchem\n",
"from paddle_quantum.qchem.layers import CrossResonanceLayer, EulerRotationLayer\n",
"\n",
"\n",
"# Your own model should inherit from `Qmodel`.\n",
"## NOTE: THIS MODEL IS ONLY DEFINED FOR DEMONSTRATION PURPOSE! \n",
"class MyAnsatz(qchem.QModel):\n",
" def __init__(self, n_qubits):\n",
" super().__init__(n_qubits)\n",
"\n",
" self.entangle = CrossResonanceLayer(self._n_qubit)\n",
" self.rot = EulerRotationLayer(self._n_qubit)\n",
"\n",
" def forward(self, state):\n",
" self._circuit = UAnsatz(self.n_qubit)\n",
"\n",
" out = self.entangle(state)\n",
" self._circuit += self.entangle.circuit\n",
"\n",
" out = self.rot(out)\n",
" self._circuit += self.rot.circuit\n",
"\n",
" out = self.entangle(out)\n",
" self._circuit += self.entangle.circuit\n",
"\n",
" return out\n",
"\n",
"# instantiate your model\n",
"my_cir = MyAnsatz(5)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"在定义好线路之后,我们就可以利用 paddlepaddle 提供的多种优化器来优化线路中的参数以获得最佳结果。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# use paddlepaddle's optimizer\n",
"import numpy as np \n",
"import paddle\n",
"\n",
"optimizer = paddle.optimizer.Adam(parameters=my_cir.parameters(), learning_rate=0.08)\n",
"\n",
"# define the loss function\n",
"## NOTE: THIS LOSS FUNCTION IS ONLY DEFINED FOR DEMONSTRATION PURPOSE!\n",
"def loss_fn(state: paddle.Tensor) -> paddle.Tensor:\n",
" return paddle.norm(state.real())\n",
"\n",
"# start learning\n",
"s0 = np.zeros((2**5,), dtype=np.complex128)\n",
"s0[0] = 1.0+0.0j\n",
"s0 = paddle.to_tensor(s0)\n",
"\n",
"for i in range(10):\n",
" loss = loss_fn(my_cir(s0))\n",
" print(f\"At {i:>d}th step: loss={loss.item():>.5f}.\")\n",
"\n",
" optimizer.clear_grad()\n",
" loss.backward()\n",
" optimizer.step()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"## 参考文献\n",
"\n",
"[1] Kandala, Abhinav, et al. \"Hardware-efficient variational quantum eigensolver for small molecules and quantum magnets.\" [Nature 549.7671 (2017): 242-246.](https://www.nature.com/articles/nature23879)\n",
"\n",
"[2] Arute, Frank, et al. \"Hartree-Fock on a superconducting qubit quantum computer.\" [Science 369.6507 (2020): 1084-1089.](https://www.science.org/doi/10.1126/science.abb9811)"
]
}
],
"metadata": {
"interpreter": {
"hash": "385f93486cadd2f2140b6b583192a2daa18c8b591e699592075836b347373dd4"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Quantum Chemistry with Paddle Quantum's qchem\n",
"*Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.*\n",
"\n",
"qchem, which builds on top of Paddle Quantum, is designed to be a toolkit for quantum chemistry research in quantum computing era. It provides high level APIs for researchers who are interested in leveraging their current quantum chemsitry calculation with quantum computing power. And it also allows experts to write customized code. qchem is currently under active development, feel free to join us by opening issues or pull requests."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Calculate ground state energy of a molecule\n",
"qchem provides `run_chem` function to calculate the ground state energy and ground state wave function. For example, let's try to calculate the ground state energy of hydrogen molecule. First, we need to import qchem."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from paddle_quantum import qchem"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Then, we need to provide chemical information required by `run_chem` function, including geometry, charge, basis function etc."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# define the geometry of hydrogen molecule, length unit use angstrom.\n",
"h2_geometry = [(\"H\", [0.0, 0.0, 0.0]), (\"H\", [0.0, 0.0, 0.74])]\n",
"charge = 0\n",
"basis_set = \"sto-3g\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, let's choose an ansatz of many-electron wave function for our ground state energy calculation. Currently, you can choose to use \"hardware efficient\" [<sup>1</sup>](#refer-1) or \"hartree fock\" [<sup>2</sup>](#refer-2) ansatz, more functionalities will be released in the future. Let's choose \"hardware efficient\" ansatz."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# call run_chem function with \"hardware efficient\" ansatz.\n",
"h2_gs_en, h2_wf_model = qchem.run_chem(\n",
" h2_geometry,\n",
" \"hardware efficient\",\n",
" basis_set, \n",
" charge\n",
")\n",
"\n",
"# additional information for optimizer can be passed using `optimizer_option` keyword argument.\n",
"h2_gs_en, h2_wf_model = qchem.run_chem(\n",
" h2_geometry,\n",
" \"hardware efficient\",\n",
" basis_set, \n",
" charge,\n",
" optimizer_option={\"learning_rate\": 0.6, \"weight_decay\": 0.9}\n",
")\n",
"\n",
"# additional information for ansatz can be passed using `ansatz_option` keyword argument, e.g.\n",
"# \"hardware efficient\" ansatz has a parameter \"cir_depth\", which can be used to specify the depth\n",
"# of quantum circuit.\n",
"h2_gs_en, h2_wf_model = qchem.run_chem(\n",
" h2_geometry,\n",
" \"hardware efficient\",\n",
" basis_set, \n",
" charge,\n",
" ansatz_option={\"cir_depth\": 5}\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can also specify `max_iters` and `a_tol` keyword arguments to control the maximum iteration cycles and convergence criteria of the optimization process. \n",
"\n",
"To try another ansatz, you just need to replace the ansatz argument to, e.g. \"hartree fock\", and run similar command.\n",
"\n",
"To see the quantum circuit for hydrogen molecule's hardware efficient ansatz, you can run `print(h2_wf_model.circuit)`."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Design your own ansatz\n",
"For those who want to try an ansatz that isn't currently included in qchem, we provide method to write your own ansatz. Writing your own ansatz is similar to defining an neural network in paddlepaddle, except that your ansatz should inherit from `Qmodel`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from paddle_quantum.circuit import UAnsatz\n",
"from paddle_quantum import qchem\n",
"from paddle_quantum.qchem.layers import CrossResonanceLayer, EulerRotationLayer\n",
"\n",
"\n",
"# Your own model should inherit from `Qmodel`.\n",
"## NOTE: THIS MODEL IS ONLY DEFINED FOR DEMONSTRATION PURPOSE! \n",
"class MyAnsatz(qchem.QModel):\n",
" def __init__(self, n_qubits):\n",
" super().__init__(n_qubits)\n",
"\n",
" self.entangle = CrossResonanceLayer(self._n_qubit)\n",
" self.rot = EulerRotationLayer(self._n_qubit)\n",
"\n",
" def forward(self, state):\n",
" self._circuit = UAnsatz(self.n_qubit)\n",
"\n",
" out = self.entangle(state)\n",
" self._circuit += self.entangle.circuit\n",
"\n",
" out = self.rot(out)\n",
" self._circuit += self.rot.circuit\n",
"\n",
" out = self.entangle(out)\n",
" self._circuit += self.entangle.circuit\n",
"\n",
" return out\n",
"\n",
"# instantiate your model\n",
"my_cir = MyAnsatz(5)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can then follow the optimization procedure [here](https://qml.baidu.com/tutorials/quantum-simulation/variational-quantum-eigensolver.html) and use any paddlepaddle optimizer to train the ansatz you have built."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# use paddlepaddle's optimizer\n",
"import numpy as np \n",
"import paddle\n",
"\n",
"optimizer = paddle.optimizer.Adam(parameters=my_cir.parameters(), learning_rate=0.08)\n",
"\n",
"# define the loss function\n",
"## NOTE: THIS LOSS FUNCTION IS ONLY DEFINED FOR DEMONSTRATION PURPOSE!\n",
"def loss_fn(state: paddle.Tensor) -> paddle.Tensor:\n",
" return paddle.norm(state.real())\n",
"\n",
"# start learning\n",
"s0 = np.zeros((2**5,), dtype=np.complex128)\n",
"s0[0] = 1.0+0.0j\n",
"s0 = paddle.to_tensor(s0)\n",
"\n",
"for i in range(10):\n",
" loss = loss_fn(my_cir(s0))\n",
" print(f\"At {i:>d}th step: loss={loss.item():>.5f}.\")\n",
"\n",
" optimizer.clear_grad()\n",
" loss.backward()\n",
" optimizer.step()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"## References\n",
"\n",
"[1] Kandala, Abhinav, et al. \"Hardware-efficient variational quantum eigensolver for small molecules and quantum magnets.\" [Nature 549.7671 (2017): 242-246.](https://www.nature.com/articles/nature23879)\n",
"\n",
"[2] Arute, Frank, et al. \"Hartree-Fock on a superconducting qubit quantum computer.\" [Science 369.6507 (2020): 1084-1089.](https://www.science.org/doi/10.1126/science.abb9811)"
]
}
],
"metadata": {
"interpreter": {
"hash": "7b343e878babc25549085ff27e754b596ec1b81bbbd70d50b28da4f6023d5bd9"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
因为 它太大了无法显示 source diff 。你可以改为 查看blob
因为 它太大了无法显示 source diff 。你可以改为 查看blob
...@@ -17,4 +17,4 @@ Paddle Quantum Library ...@@ -17,4 +17,4 @@ Paddle Quantum Library
""" """
name = "paddle_quantum" name = "paddle_quantum"
__version__ = "2.1.2" __version__ = "2.1.3"
...@@ -26,7 +26,7 @@ from paddle import imag, real, reshape, kron, matmul, trace ...@@ -26,7 +26,7 @@ from paddle import imag, real, reshape, kron, matmul, trace
from paddle_quantum.utils import partial_trace, dagger, pauli_str_to_matrix from paddle_quantum.utils import partial_trace, dagger, pauli_str_to_matrix
from paddle_quantum import shadow from paddle_quantum import shadow
from paddle_quantum.intrinsic import * from paddle_quantum.intrinsic import *
from paddle_quantum.state import density_op,vec from paddle_quantum.state import density_op, vec
__all__ = [ __all__ = [
"UAnsatz", "UAnsatz",
...@@ -60,38 +60,15 @@ class UAnsatz: ...@@ -60,38 +60,15 @@ class UAnsatz:
# Record history of adding gates to the circuit # Record history of adding gates to the circuit
self.__history = [] self.__history = []
def expand(self,new_n):
"""
为原来的量子电路进行比特数扩展
Args:
new_n(int):扩展后的量子比特数
"""
assert new_n>=self.n,'扩展后量子比特数要大于原量子比特数'
diff = new_n-self.n
dim = 2**diff
if self.__state is not None:
if self.__run_mode=='density_matrix':
shape = (dim,dim)
_state = paddle.to_tensor(density_op(diff))
elif self.__run_mode=='state_vector':
shape = (dim,)
_state = paddle.to_tensor(vec(0,diff))
_state= paddle.reshape(_state,shape)
_state = kron(self.__state,_state)
self.__state = _state
self.n = new_n
def __add__(self, cir): def __add__(self, cir):
r"""重载加法 ‘+’ 运算符,用于拼接两个维度相同的电路 r"""重载加法 ‘+’ 运算符,用于拼接两个维度相同的电路
Args: Args:
cir (UAnsatz): 拼接到现有电路上的电路 cir (UAnsatz): 拼接到现有电路上的电路
Returns: Returns:
UAnsatz: 拼接后的新电路 UAnsatz: 拼接后的新电路
代码示例: 代码示例:
.. code-block:: python .. code-block:: python
...@@ -113,19 +90,19 @@ class UAnsatz: ...@@ -113,19 +90,19 @@ class UAnsatz:
print(cir3) print(cir3)
:: ::
cir1: cir1:
--H-- --H--
--H-- --H--
cir2: cir2:
--*-- --*--
| |
--x-- --x--
cir3: cir3:
--H----*-- --H----*--
| |
--H----x-- --H----x--
""" """
...@@ -304,13 +281,13 @@ class UAnsatz: ...@@ -304,13 +281,13 @@ class UAnsatz:
The printed circuit is: The printed circuit is:
--H----Ry(-0.14)----*-------------------X----Ry(-0.77)----*-------------------X-- --H----Ry(-0.14)----*-------------------X----Ry(-0.77)----*-------------------X--
| | | | | | | |
--H----Ry(-1.00)----X----*--------------|----Ry(-0.83)----X----*--------------|-- --H----Ry(-1.00)----X----*--------------|----Ry(-0.83)----X----*--------------|--
| | | | | | | |
--H----Ry(-1.88)---------X----*---------|----Ry(-0.98)---------X----*---------|-- --H----Ry(-1.88)---------X----*---------|----Ry(-0.98)---------X----*---------|--
| | | | | | | |
--H----Ry(1.024)--------------X----*----|----Ry(-0.37)--------------X----*----|-- --H----Ry(1.024)--------------X----*----|----Ry(-0.37)--------------X----*----|--
| | | | | | | |
--H----Ry(1.905)-------------------X----*----Ry(-1.82)-------------------X----*-- --H----Ry(1.905)-------------------X----*----Ry(-1.82)-------------------X----*--
""" """
length, gate = self._count_history() length, gate = self._count_history()
...@@ -419,6 +396,29 @@ class UAnsatz: ...@@ -419,6 +396,29 @@ class UAnsatz:
return return_str return return_str
def expand(self, qubit_num):
"""
为原来的量子电路进行比特数扩展
Args:
qubit_num (int): 扩展后的量子比特数
"""
assert qubit_num >= self.n, '扩展后量子比特数要大于原量子比特数'
diff = qubit_num - self.n
dim = 2 ** diff
if self.__state is not None:
if self.__run_mode == 'density_matrix':
shape = (dim, dim)
_state = paddle.to_tensor(density_op(diff))
elif self.__run_mode == 'state_vector':
shape = (dim,)
_state = paddle.to_tensor(vec(0, diff))
_state = paddle.reshape(_state, shape)
_state = kron(self.__state, _state)
self.__state = _state
self.n = qubit_num
def run_state_vector(self, input_state=None, store_state=True): def run_state_vector(self, input_state=None, store_state=True):
r"""运行当前的量子电路,输入输出的形式为态矢量。 r"""运行当前的量子电路,输入输出的形式为态矢量。
...@@ -1160,7 +1160,7 @@ class UAnsatz: ...@@ -1160,7 +1160,7 @@ class UAnsatz:
.. math:: .. math::
\begin{align} \begin{align}
CNOT &=|0\rangle \langle 0|\otimes I + |1 \rangle \langle 1|\otimes X\\ CY &=|0\rangle \langle 0|\otimes I + |1 \rangle \langle 1|\otimes Y\\
&= &=
\begin{bmatrix} \begin{bmatrix}
1 & 0 & 0 & 0 \\ 1 & 0 & 0 & 0 \\
...@@ -1197,7 +1197,7 @@ class UAnsatz: ...@@ -1197,7 +1197,7 @@ class UAnsatz:
.. math:: .. math::
\begin{align} \begin{align}
CNOT &=|0\rangle \langle 0|\otimes I + |1 \rangle \langle 1|\otimes X\\ CZ &=|0\rangle \langle 0|\otimes I + |1 \rangle \langle 1|\otimes Z\\
&= &=
\begin{bmatrix} \begin{bmatrix}
1 & 0 & 0 & 0 \\ 1 & 0 & 0 & 0 \\
...@@ -1915,9 +1915,9 @@ class UAnsatz: ...@@ -1915,9 +1915,9 @@ class UAnsatz:
:: ::
------------x----Rx(3.142)----Ryy(1.57)--------------- ------------x----Rx(3.142)----Ryy(1.57)---------------
| | | |
------------|-----------------Ryy(1.57)----Rz(0.785)-- ------------|-----------------Ryy(1.57)----Rz(0.785)--
| |
--H---SDG---*--------H-------------------------------- --H---SDG---*--------H--------------------------------
""" """
history, param = self._get_history() history, param = self._get_history()
...@@ -1975,15 +1975,15 @@ class UAnsatz: ...@@ -1975,15 +1975,15 @@ class UAnsatz:
:: ::
--Rx(3.142)----Ryy(1.57)-------------*------ --Rx(3.142)----Ryy(1.57)-------------*------
| | | |
---------------Ryy(1.57)----z----Rz(0.785)-- ---------------Ryy(1.57)----z----Rz(0.785)--
| |
------H-----------SDG-------*--------H------ ------H-----------SDG-------*--------H------
--Rx(3.142)----Ryy(1.57)----z-------------*------ --Rx(3.142)----Ryy(1.57)----z-------------*------
| | | | | |
---------------Ryy(1.57)----|----z----Rz(0.785)-- ---------------Ryy(1.57)----|----z----Rz(0.785)--
| | | |
------H------------S--------*----*--------H------ ------H------------S--------*----*--------H------
""" """
history, param = self._get_history() history, param = self._get_history()
...@@ -2035,9 +2035,9 @@ class UAnsatz: ...@@ -2035,9 +2035,9 @@ class UAnsatz:
:: ::
------------z----U-- ------------z----U--
| |
------------|------- ------------|-------
| |
--H---SDG---*----H-- --H---SDG---*----H--
""" """
history, param = self._get_history() history, param = self._get_history()
...@@ -2101,15 +2101,15 @@ class UAnsatz: ...@@ -2101,15 +2101,15 @@ class UAnsatz:
:: ::
-----------------x-- -----------------x--
| |
------------z----U-- ------------z----U--
| |
--H---SDG---*----H-- --H---SDG---*----H--
------------z---------x-- ------------z---------x--
| | | |
------------|----z----U-- ------------|----z----U--
| | | |
--H----S----*----*----H-- --H----S----*----*----H--
""" """
history, param = self._get_history() history, param = self._get_history()
...@@ -3098,7 +3098,7 @@ class UAnsatz: ...@@ -3098,7 +3098,7 @@ class UAnsatz:
def update_param(self, new_param): def update_param(self, new_param):
r"""用得到的新参数列表更新电路参数列表中的可训练的参数。 r"""用得到的新参数列表更新电路参数列表中的可训练的参数。
Args: Args:
new_param (list): 新的参数列表 new_param (list): 新的参数列表
...@@ -3108,8 +3108,11 @@ class UAnsatz: ...@@ -3108,8 +3108,11 @@ class UAnsatz:
j = 0 j = 0
for i in range(len(self.__param)): for i in range(len(self.__param)):
if not self.__param[i].stop_gradient: if not self.__param[i].stop_gradient:
self.__param[i] = paddle.to_tensor(new_param[j], 'float64') if not isinstance(new_param[j], paddle.Tensor):
self.__param[i].stop_gradient = False self.__param[i] = paddle.to_tensor(new_param[j], 'float64')
self.__param[i].stop_gradient = False
else:
self.__param[i] = new_param[j]
j += 1 j += 1
self.run_state_vector() self.run_state_vector()
return self.__param return self.__param
......
# Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
dataset: To learn more about the functions and properties of this application,
you could check the corresponding Jupyter notebook under the Tutorial folder.
"""
import math
import random
from math import sqrt
import time
import paddle.vision.transforms as transform
import numpy as np
import paddle
from paddle_quantum.circuit import UAnsatz
from paddle.fluid.layers import reshape
from sklearn.model_selection import train_test_split
from sklearn import datasets
__all__ = [
"VisionDataset",
"SimpleDataset",
"MNIST",
"FashionMNIST",
"Iris",
"BreastCancer"
]
# data modes
DATAMODE_TRAIN = "train"
DATAMODE_TEST = "test"
# encoding methods
ANGLE_ENCODING = "angle_encoding"
AMPLITUDE_ENCODING = "amplitude_encoding"
PAULI_ROTATION_ENCODING = "pauli_rotation_encoding"
LINEAR_ENTANGLED_ENCODING = "linear_entangled_encoding"
REAL_ENTANGLED_ENCODING = "real_entangled_encoding"
COMPLEX_ENTANGLED_ENCODING = "complex_entangled_encoding"
IQP_ENCODING = "IQP_encoding"
# downscaling method
DOWNSCALINGMETHOD_PCA = "PCA"
DOWNSCALINGMETHOD_RESIZE = "resize"
def _normalize(x):
r"""normalize vector ``x`` and the maximum will be pi. This is an internal function.
Args:
x (ndarray): 需要归一化的向量
Returns:
ndarray: 归一化之后的向量
"""
xx = np.abs(x)
if xx.max() > 0:
return x * np.pi / xx.max()
else:
return x
def _normalize_image(x):
r"""normalize image vector ``x`` and the maximum will be pi. This is an internal function.
Args:
x (ndarray): 需要归一化的图片向量
Returns:
ndarray: 归一化之后的向量
"""
return x * np.pi / 256
def _crop(images, border):
r"""crop ``images`` according to ``border``. This is an internal function.
Args:
images (list/ndarray): 每一个元素是拉成一维的图片向量
border(list): 裁剪的边界,从第一个元素切到第二个元素,比如说[4,24]就是从图片的第四行第四列到第24行第24列
Returns:
new_images(list): 裁剪之后被拉成一维的图片向量组成的list
"""
new_images = []
for i in range(len(images)):
size = int(sqrt(len(images[i])))
temp_image = images[i].reshape((size, size))
temp_image = temp_image[border[0]:border[1], border[0]:border[1]]
new_images.append(temp_image.flatten())
return new_images
class Dataset(object):
r"""所有数据集的基类,集成了多种量子编码方法。
"""
def __init__(self):
return
def data2circuit(self, classical_data, encoding, num_qubits, can_describe_dimension, split_circuit,
return_state, is_image=False):
r"""将输入的经典数据 ``classical_data`` 用编码方式 ``encoding`` 编码成量子态,这里的经典数据经过了截断或者补零,因而可以正好被编码。
Args:
classical_data (list): 待编码的向量,ndarray 组成的 list,经过了截断或者补零,刚好可以被编码
encoding (str): 编码方式,参见 MNIST 编码注释
num_qubits (int): 量子比特数目
can_describe_dimension (int): 以 ``encoding`` 编码方式可以编码的数目,比如说振幅编码为 ``2 ** n`` ,其他编码因为可以进行层层堆叠需要计算
split_circuit (bool): 是否切分电路
return_state (bool): 是否返回量子态
is_image (bool): 是否是图片,如果是图片,归一化方法不太一样
Returns:
List: 如果 ``return_state == True`` ,返回编码后的量子态,否则返回编码的电路
"""
quantum_states = classical_data.copy()
quantum_circuits = classical_data.copy()
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)):
built_in_amplitude_enc = UAnsatz(num_qubits)
x = paddle.to_tensor(_normalize(classical_data[i]))
if is_image:
x = paddle.to_tensor(_normalize_image(classical_data[i]))
state = built_in_amplitude_enc.amplitude_encoding(x, 'state_vector')
quantum_states[i] = state.numpy()
elif encoding == ANGLE_ENCODING:
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]))
if is_image:
param = paddle.to_tensor(_normalize_image(classical_data[i]))
param = reshape(param, (depth, num_qubits, 1))
which_qubits = [k for k in range(num_qubits)]
if split_circuit:
quantum_circuits[i] = []
for repeat in range(depth):
circuit = UAnsatz(num_qubits)
for k, q in enumerate(which_qubits):
circuit.ry(param[repeat][k][0], q)
quantum_circuits[i].append(circuit)
else:
circuit = UAnsatz(num_qubits)
for repeat in range(depth):
for k, q in enumerate(which_qubits):
circuit.ry(param[repeat][k][0], q)
state_out = circuit.run_state_vector()
quantum_states[i] = state_out.numpy()
quantum_circuits[i] = [circuit]
elif encoding == IQP_ENCODING:
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]))
if is_image:
param = paddle.to_tensor(_normalize_image(classical_data[i]))
param = reshape(param, (depth, num_qubits))
if split_circuit:
quantum_circuits[i] = []
for repeat in range(depth):
circuit = UAnsatz(num_qubits)
S = []
for k in range(num_qubits - 1):
S.append([k, k + 1])
# r 是 U 重复的次数
r = 1
circuit.iqp_encoding(param[repeat], r, S)
quantum_circuits[i].append(circuit)
else:
circuit = UAnsatz(num_qubits)
for repeat in range(depth):
temp_circuit = UAnsatz(num_qubits)
S = []
for k in range(num_qubits - 1):
S.append([k, k + 1])
# r 是 U 重复的次数
r = 1
temp_circuit.iqp_encoding(param[repeat], r, S)
circuit = circuit + temp_circuit
state_out = circuit.run_state_vector()
quantum_states[i] = state_out.numpy()
quantum_circuits[i] = [circuit]
elif encoding == PAULI_ROTATION_ENCODING:
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]))
if is_image:
param = paddle.to_tensor(_normalize_image(classical_data[i]))
param = reshape(param, (depth, num_qubits, 3))
which_qubits = [k for k in range(num_qubits)]
if split_circuit:
quantum_circuits[i] = []
for repeat in range(depth):
circuit = UAnsatz(num_qubits)
for k, q in enumerate(which_qubits):
circuit.ry(param[repeat][k][0], q)
circuit.rz(param[repeat][k][1], q)
circuit.ry(param[repeat][k][2], q)
quantum_circuits[i].append(circuit)
else:
circuit = UAnsatz(num_qubits)
for repeat in range(depth):
for k, q in enumerate(which_qubits):
circuit.ry(param[repeat][k][0], q)
circuit.rz(param[repeat][k][1], q)
circuit.ry(param[repeat][k][2], q)
state_out = circuit.run_state_vector()
quantum_states[i] = state_out.numpy()
quantum_circuits[i] = [circuit]
elif encoding == LINEAR_ENTANGLED_ENCODING:
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]))
if is_image:
param = paddle.to_tensor(_normalize_image(classical_data[i]))
param = reshape(param, (depth, num_qubits, 2))
which_qubits = [k for k in range(num_qubits)]
if split_circuit:
quantum_circuits[i] = []
for j in range(depth):
circuit = UAnsatz(num_qubits)
for k, q in enumerate(which_qubits):
circuit.ry(param[j][k][0], q)
for k in range(len(which_qubits) - 1):
circuit.cnot([which_qubits[k], which_qubits[k + 1]])
for k, q in enumerate(which_qubits):
circuit.rz(param[j][k][1], q)
for k in range(len(which_qubits) - 1):
circuit.cnot([which_qubits[k + 1], which_qubits[k]])
quantum_circuits[i].append(circuit)
else:
circuit = UAnsatz(num_qubits)
for j in range(depth):
for k, q in enumerate(which_qubits):
circuit.ry(param[j][k][0], q)
for k in range(len(which_qubits) - 1):
circuit.cnot([which_qubits[k], which_qubits[k + 1]])
for k, q in enumerate(which_qubits):
circuit.rz(param[j][k][1], q)
for k in range(len(which_qubits) - 1):
circuit.cnot([which_qubits[k + 1], which_qubits[k]])
state_out = circuit.run_state_vector()
quantum_states[i] = state_out.numpy()
quantum_circuits[i] = [circuit]
elif encoding == REAL_ENTANGLED_ENCODING:
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]))
if is_image:
param = paddle.to_tensor(_normalize_image(classical_data[i]))
param = reshape(param, (depth, num_qubits, 1))
which_qubits = [k for k in range(num_qubits)]
if split_circuit:
quantum_circuits[i] = []
for repeat in range(depth):
circuit = UAnsatz(num_qubits)
for k, q in enumerate(which_qubits):
circuit.ry(param[repeat][k][0], q)
for k in range(len(which_qubits) - 1):
circuit.cnot([which_qubits[k], which_qubits[k + 1]])
circuit.cnot([which_qubits[-1], which_qubits[0]])
quantum_circuits[i].append(circuit)
else:
circuit = UAnsatz(num_qubits)
for repeat in range(depth):
for k, q in enumerate(which_qubits):
circuit.ry(param[repeat][k][0], q)
for k in range(len(which_qubits) - 1):
circuit.cnot([which_qubits[k], which_qubits[k + 1]])
circuit.cnot([which_qubits[-1], which_qubits[0]])
state_out = circuit.run_state_vector()
quantum_states[i] = state_out.numpy()
quantum_circuits[i] = [circuit]
elif encoding == COMPLEX_ENTANGLED_ENCODING:
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]))
if is_image:
param = paddle.to_tensor(_normalize_image(classical_data[i]))
param = reshape(param, (depth, num_qubits, 3))
which_qubits = [k for k in range(num_qubits)]
if split_circuit:
quantum_circuits[i] = []
for repeat in range(depth):
circuit = UAnsatz(num_qubits)
for k, q in enumerate(which_qubits):
circuit.u3(param[repeat][k][0], param[repeat][k][1], param[repeat][k][2], q)
for k in range(len(which_qubits) - 1):
circuit.cnot([which_qubits[k], which_qubits[k + 1]])
circuit.cnot([which_qubits[-1], which_qubits[0]])
quantum_circuits[i].append(circuit)
else:
circuit = UAnsatz(num_qubits)
for repeat in range(depth):
for k, q in enumerate(which_qubits):
circuit.u3(param[repeat][k][0], param[repeat][k][1], param[repeat][k][2], q)
for k in range(len(which_qubits) - 1):
circuit.cnot([which_qubits[k], which_qubits[k + 1]])
circuit.cnot([which_qubits[-1], which_qubits[0]])
state_out = circuit.run_state_vector()
quantum_states[i] = state_out.numpy()
quantum_circuits[i] = [circuit]
return quantum_states, quantum_circuits
def filter_class(self, x, y, classes, data_num, need_relabel, seed=0):
r"""将输入的 ``x`` , ``y`` 按照 ``classes`` 给出的类别进行筛选,数目为 ``data_num`` 。
Args:
x (ndarray/list): 样本的特征
y (ndarray/list): 样本标签, ``classes`` 是其中某几个标签的取值
classes (list): 需要筛选的类别
data_num (int): 筛选出来的样本数目
need_relabel (bool): 将原有类别按照顺序重新标记为 0、1、2 等新的名字,比如传入 ``[1,2]`` , 重新标记之后变为 ``[0,1]`` 主要用于二分类
seed (int): 随机种子,默认为 ``0``
Returns:
tuple: 包含如下元素:
- new_x (list): 筛选出的特征
- new_y (list): 对应于 ``new_x`` 的标签
"""
new_x = []
new_y = []
if need_relabel:
for i in range(len(x)):
if y[i] in classes:
new_x.append(x[i])
new_y.append(classes.index(y[i]))
else:
for i in range(len(x)):
if y[i] in classes:
new_x.append(x[i])
new_y.append(y[i])
# sample to data_num randomly
if data_num > 0 and data_num < len(new_x):
random_index = [k for k in range(len(new_x))]
random.seed(seed)
random.shuffle(random_index)
random_index = random_index[:data_num]
filter_x = []
filter_y = []
for index in random_index:
filter_x.append(new_x[index])
filter_y.append(new_y[index])
return filter_x, filter_y
return new_x, new_y
class VisionDataset(Dataset):
r"""图片数据集类,通过继承 VisionDataset 类,用户可以快速生成自己的图片量子数据。
Attributes:
original_images (ndarray): 图片经过类别过滤,但是还没有降维、补零的特征,是一个一维向量(可调用 ``reshape()`` 函数转成图片)
classical_image_vectors (ndarray): 经过类别过滤和降维、补零等操作之后的特征,并未编码为量子态
quantum_image_states (paddle.tensor): 经过类别过滤之后的所有特征经编码形成的量子态
quantum_image_circuits (list): 所有特征编码的电路
"""
def __init__(self, figure_size):
r"""构造函数
Args:
figure_size (int): 图片大小,也就是长和高的数值
"""
Dataset.__init__(self)
self.figure_size = figure_size
return
# The encode function only needs to import images to form one-dimensional vector features.
# The pre-processing of images (except dimensionality reduction) is completed before the import of features
def encode(self, feature, encoding, num_qubits, split_circuit=False,
downscaling_method=DOWNSCALINGMETHOD_RESIZE, target_dimension=-1, return_state=True, full_return=False):
r"""根据降尺度方式、目标尺度、编码方式、量子比特数目进行编码。只需要输入一维图片向量就行。
Args:
feature (list/ndarray): 一维图片向量组成的list/ndarray
encoding (str): ``"angle_encoding"`` 表示角度编码,一个量子比特编码一个旋转门; ``"amplitude_encoding"`` 表示振幅编码;
``"pauli_rotation_encoding"`` 表示SU(3)的角度编码; 还有 ``"linear_entangled_encoding"`` ,
``"real_entangled_encoding"`` , ``"complex_entangled_encoding"`` 三种纠缠编码和 ``"IQP_encoding"`` 编码
num_qubits (int): 编码后的量子比特数目
split_circuit (bool): 是否需要切分电路。除了振幅之外的所有电路都会存在堆叠的情况,如果选择 ``True`` 就将块与块分开
downscaling_method (str): 包括 ``"PCA"`` 和 ``"resize"``
target_dimension (int): 降维之后的尺度大小,如果是 ``"PCA"`` ,不能超过图片大小;如果是 ``"resize"`` ,不能超过原图大小
return_state (bool): 是否返回量子态,如果是 ``False`` 返回量子电路
Returns:
tuple: 包含如下元素:
- quantum_image_states (paddle.tensor): 量子态,只有 ``full_return==True`` 或者 ``return_state==True`` 的时候会返回
- quantum_image_circuits (list): 所有特征编码的电路, 只有 ``full_return==False`` 或者 ``return_state==True`` 的时候会返回
- original_images (ndarray): 图片经过类别过滤,但是还没有降维、补零的特征,是一个一维向量(可以 reshape 成图片),只有 ``return_state==True`` 的时候会返回
- classical_image_vectors (ndarray): 经过类别过滤和降维、补零等操作之后的特征,并未编码为量子态,只有 ``return_state==True`` 的时候会返回
"""
assert num_qubits > 0
if encoding in [IQP_ENCODING, COMPLEX_ENTANGLED_ENCODING, REAL_ENTANGLED_ENCODING,
LINEAR_ENTANGLED_ENCODING]:
assert num_qubits > 1
if type(feature) == np.ndarray:
feature = list(feature)
# The first step: judge whether `target_dimension` is reasonable
if target_dimension > -1:
if downscaling_method == DOWNSCALINGMETHOD_PCA:
if target_dimension > self.figure_size:
raise Exception("PCA dimension should be less than {}.".format(self.figure_size))
elif downscaling_method == DOWNSCALINGMETHOD_RESIZE:
if int(sqrt(target_dimension)) ** 2 != target_dimension: # not a square
raise Exception("Resize dimension should be a square.")
else:
raise Exception("Downscaling methods can only be resize and PCA.")
else:
if downscaling_method == DOWNSCALINGMETHOD_PCA:
target_dimension = self.figure_size
elif downscaling_method == DOWNSCALINGMETHOD_RESIZE:
target_dimension = self.figure_size ** 2
# The second step: calculate `can_describe_dimension`
if encoding == AMPLITUDE_ENCODING: # amplitude encoding, encoding 2^N-dimension feature
self.can_describe_dimension = 2 ** num_qubits
elif encoding == LINEAR_ENTANGLED_ENCODING:
one_block_param = 2 * num_qubits
self.can_describe_dimension = math.ceil(target_dimension / one_block_param) * one_block_param
elif encoding in [REAL_ENTANGLED_ENCODING, ANGLE_ENCODING, IQP_ENCODING]:
one_block_param = 1 * num_qubits
self.can_describe_dimension = math.ceil(target_dimension / one_block_param) * one_block_param
elif encoding in [COMPLEX_ENTANGLED_ENCODING, PAULI_ROTATION_ENCODING]:
one_block_param = 3 * num_qubits
self.can_describe_dimension = math.ceil(target_dimension / one_block_param) * one_block_param
else:
raise Exception("Invalid encoding methods!")
self.dimension = target_dimension
# The third step: download MNIST data from paddlepaddle and crop or fill the vector to ``can_describe_vector``
self.original_images = np.array(feature)
self.classical_image_vectors = feature.copy()
# What need to mention if ``Resize`` needs uint8, but MNIST in paddle is float32, so we should change its type.
if downscaling_method == DOWNSCALINGMETHOD_RESIZE:
# iterating all items
for i in range(len(self.classical_image_vectors)):
cur_image = self.classical_image_vectors[i].astype(np.uint8)
new_size = int(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
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]
else:
self.classical_image_vectors[i] = np.append(self.classical_image_vectors[i], np.array(
[0.0] * (self.can_describe_dimension - len(self.classical_image_vectors[i]))))
elif downscaling_method == DOWNSCALINGMETHOD_PCA:
for i in range(len(self.classical_image_vectors)):
U, s, V = np.linalg.svd(self.classical_image_vectors[i].reshape((self.figure_size, self.figure_size)))
s = s[:self.dimension].astype(np.float64)
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)
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)
self.classical_image_vectors = np.array(self.classical_image_vectors)
if return_state:
self.quantum_image_states = paddle.to_tensor(np.array(self.quantum_image_states)) # transfer to tensor
if full_return:
return self.quantum_image_states, self.quantum_image_circuits, self.original_images, \
self.classical_image_vectors
else:
if return_state:
return self.quantum_image_states
else:
return self.quantum_image_circuits
class MNIST(VisionDataset):
r"""MNIST 数据集,它继承了 VisionDataset 图片数据集类。
Attributes:
original_images(ndarray): 图片经过类别过滤,但是还没有降维、补零的特征,是一个一维向量(可调用 ``reshape()`` 方法转成图片)
classical_image_vectors(ndarray): 经过类别过滤和降维、补零等操作之后的特征,并未编码为量子态
quantum_image_states(paddle.tensor): 经过类别过滤之后的所有特征经编码形成的量子态
quantum_image_circuits(list): 所有特征编码的电路
labels(ndarray): 经过类别过滤之后的所有标签
代码示例:
.. code-block:: python
from paddle_quantum.dataset import MNIST
# main parameters
training_data_num = 80
testing_data_num = 20
qubit_num = 4
# acquiring training dataset
train_dataset = MNIST(mode='train', encoding='pauli_rotation_encoding', num_qubits=qubit_num, classes=[3,6],
data_num=training_data_num,need_cropping=True,
downscaling_method='resize', target_dimension=16, return_state=True)
# acquiring testing dataset
val_dataset = MNIST(mode='test', encoding='pauli_rotation_encoding', num_qubits=qubit_num, classes=[3,6],
data_num=testing_data_num,need_cropping=True,
downscaling_method='resize', target_dimension=16,return_state=True)
# acquiring features and labels
train_x, train_y = train_dataset.quantum_image_states, train_dataset.labels # paddle.tensor, ndarray
test_x, test_y = val_dataset.quantum_image_states, val_dataset.labels
print(train_x[0])
print(train_y[0])
"""
def __init__(self, mode, encoding, num_qubits, classes, data_num=-1, split_circuit=False,
downscaling_method=DOWNSCALINGMETHOD_RESIZE, target_dimension=-1, need_cropping=True,
need_relabel=True, return_state=True, seed=0):
r"""构造函数
Args:
mode (str): 数据模式,包括 ``"train"`` 和 ``"test"``
encoding (str): ``"angle_encoding"`` 表示角度编码,一个量子比特编码一个旋转门; ``"amplitude_encoding"`` 表示振幅编码;
``"pauli_rotation_encoding"`` 表示SU(3)的角度编码; 还有 ``"linear_entangled_encoding"`` ,
``"real_entangled_encoding"`` , ``"complex_entangled_encoding"`` 三种纠缠编码和 ``"IQP_encoding"`` 编码
num_qubits (int): 编码后的量子比特数目
classes (list): 用列表给出需要的类别,类别用数字标签表示,不支持传入名字
data_num (int): 使用的数据量大小,这样可以不用所有数据都进行编码,这样会很慢
split_circuit (bool): 是否需要切分电路。除了振幅之外的所有电路都会存在堆叠的情况,如果选择 ``True`` 就将块与块分开
need_cropping (bool): 是否需要裁边,如果为 ``True`` ,则从 ``image[0:27][0:27]`` 裁剪为 ``image[4:24][4:24]``
need_relabel (bool): 将原有类别按照顺序重新标记为 0,1,2 等新的名字,比如传入 ``[1,2]`` ,重新标记之后变为 ``[0,1]`` ,主要用于二分类
downscaling_method (str): 包括 ``"PCA"`` 和 ``"resize"``
target_dimension (int): 降维之后的尺度大小,如果是 ``"PCA"`` ,不能超过图片大小;如果是 ``"resize"`` ,不能超过原图大小
return_state (bool): 是否返回量子态,如果是 ``False`` 返回量子电路
seed (int): 筛选样本的随机种子,默认为 ``0``
"""
VisionDataset.__init__(self, 28)
if need_cropping:
self.figure_size = 20
# Download data from paddlepaddle
if mode == DATAMODE_TRAIN:
train_dataset = paddle.vision.datasets.MNIST(mode='train')
feature, self.labels = self.filter_class(train_dataset.images, train_dataset.labels,
classes=classes,
data_num=data_num, need_relabel=need_relabel, seed=seed)
if need_cropping:
feature = _crop(feature, [4, 24])
elif mode == DATAMODE_TEST:
test_dataset = paddle.vision.datasets.MNIST(mode='test')
# test_dataset.images is now a list of (784,1) shape
feature, self.labels = self.filter_class(test_dataset.images, test_dataset.labels,
classes=classes,
data_num=data_num, need_relabel=need_relabel, seed=seed)
if need_cropping:
feature = _crop(feature, [4, 24])
else:
raise Exception("data mode can only be train and test.")
# Start to encode
self.quantum_image_states, self.quantum_image_circuits, self.original_images, self.classical_image_vectors = \
self.encode(feature, encoding, num_qubits, split_circuit, downscaling_method, target_dimension,
return_state, True)
self.labels = np.array(self.labels)
def __len__(self):
return len(self.quantum_image_states)
class FashionMNIST(VisionDataset):
r""" FashionMNIST 数据集,它继承了 VisionDataset 图片数据集类
Attributes:
original_images (ndarray): 图片经过类别过滤,但是还没有降维、补零的特征,是一个一维向量(可调用 ``reshape()`` 方法转成图片)
classical_image_vectors (ndarray): 经过类别过滤和降维、补零等操作之后的特征,并未编码为量子态
quantum_image_states (paddle.tensor): 经过类别过滤之后的所有特征经编码形成的量子态
quantum_image_circuits (list): 所有特征编码的电路
labels (ndarray): 经过类别过滤之后的所有标签
代码示例:
.. code-block:: python
from paddle_quantum.dataset import FashionMNIST
training_data_num=80
testing_data_num=20
qubit_num=4
# acquiring training dataset
train_dataset = FashionMNIST(mode='train', encoding='pauli_rotation_encoding', num_qubits=qubit_num, classes=[3,6],
data_num=training_data_num,downscaling_method='resize', target_dimension=16, return_state=True)
# 验acquiring testing dataset
val_dataset = FashionMNIST(mode='test', encoding='pauli_rotation_encoding', num_qubits=qubit_num, classes=[3,6],
data_num=testing_data_num,downscaling_method='resize', target_dimension=16,return_state=True)
# acquiring features and labels
train_x, train_y = train_dataset.quantum_image_states, train_dataset.labels # paddle.tensor, ndarray
test_x, test_y = val_dataset.quantum_image_states, val_dataset.labels
print(train_x[0])
print(train_y[0])
"""
def __init__(self, mode, encoding, num_qubits, classes, data_num=-1, split_circuit=False,
downscaling_method=DOWNSCALINGMETHOD_RESIZE, target_dimension=-1,
need_relabel=True, return_state=True, seed=0):
r""" 构造函数
Args:
mode (str): 数据模式,包括 ``"train"`` 和 ``"test"``
encoding (str): ``"angle_encoding"`` 表示角度编码,一个量子比特编码一个旋转门; ``"amplitude_encoding"`` 表示振幅编码;
``"pauli_rotation_encoding"`` 表示SU(3)的角度编码;还有 ``"linear_entangled_encoding"`` 、
``"real_entangled_encoding"`` 、 ``"complex_entangled_encoding"`` 三种纠缠编码和 ``"IQP_encoding"`` 编码
num_qubits (int): 编码后的量子比特数目
classes (list): 用列表给出需要的类别,类别用数字标签表示,不支持传入名字
data_num (int): 使用的数据量大小,这样可以不用所有数据都进行编码,这样会很慢
split_circuit (bool): 是否需要切分电路。除了振幅之外的所有电路都会存在堆叠的情况,如果选择true就将块与块分开
need_relabel (bool): 将原有类别按照顺序重新标记为0,1,2等新的名字,比如传入 ``[1,2]`` ,重新标记之后变为 ``[0,1]`` ,主要用于二分类
downscaling_method (str): 包括 ``"PCA"`` 和 ``"resize"``
target_dimension (int): 降维之后的尺度大小,如果是 ``"PCA"`` ,不能超过图片大小;如果是 ``"resize"`` ,不能超过原图大小
return_state (bool): 是否返回量子态,如果是 ``False`` 返回量子电路
seed (int): 随机种子,默认为 ``0``
"""
VisionDataset.__init__(self, 28)
# Download data from paddlepaddle
if mode == DATAMODE_TRAIN:
train_dataset = paddle.vision.datasets.FashionMNIST(mode='train')
feature, self.labels = self.filter_class(train_dataset.images, train_dataset.labels,
classes=classes,
data_num=data_num, need_relabel=need_relabel, seed=seed)
elif mode == DATAMODE_TEST:
test_dataset = paddle.vision.datasets.FashionMNIST(mode='test')
# test_dataset.images is now a list of (784,1) shape
feature, self.labels = self.filter_class(test_dataset.images, test_dataset.labels,
classes=classes,
data_num=data_num, need_relabel=need_relabel, seed=seed)
else:
raise Exception("data mode can only be train and test.")
# Start to encode
self.quantum_image_states, self.quantum_image_circuits, self.original_images, self.classical_image_vectors = \
self.encode(feature, encoding, num_qubits, split_circuit, downscaling_method, target_dimension,
return_state, True)
self.labels = np.array(self.labels)
def __len__(self):
return len(self.quantum_image_states)
class SimpleDataset(Dataset):
r""" 用于不需要降维的简单分类数据。用户可以通过继承 ``SimpleDataset`` ,将自己的分类数据变为量子态。下面的几个属性也会被继承。
Attributes:
quantum_states (ndarray): 经过类别过滤之后的所有特征经编码形成的量子态
quantum_circuits (list): 所有特征编码的电路
origin_feature (ndarray): 经过类别过滤之后的所有特征,并未编码为量子态
feature (ndarray): ``origin_feature`` 经过了补零之后的特征, ``quantum_states`` 就是将 ``feature`` 编码之后的结果
代码示例:
.. code-block:: python
from paddle_quantum.dataset import SimpleDataset
def circle_data_point_generator(Ntrain, Ntest, boundary_gap, seed_data):
# generate binary classification data with circle boundaries
# The former Ntrain samples are training data, the latter Ntest samples are testing data.
train_x, train_y = [], []
num_samples, seed_para = 0, 0
while num_samples < Ntrain + Ntest:
np.random.seed((seed_data + 10) * 1000 + seed_para + num_samples)
data_point = np.random.rand(2) * 2 - 1 # generator two-dimension vectors in [-1, 1]
# If the norm is below (0.7 - gap), the data point is mark as zero
if np.linalg.norm(data_point) < 0.7 - boundary_gap / 2:
train_x.append(data_point)
train_y.append(0.)
num_samples += 1
# If the norm is over (0.7 + gap), the data point is mark as one
elif np.linalg.norm(data_point) > 0.7 + boundary_gap / 2:
train_x.append(data_point)
train_y.append(1.)
num_samples += 1
else:
seed_para += 1
train_x = np.array(train_x).astype("float64")
train_y = np.array([train_y]).astype("float64").T
print("The dimension of the training data: x {} 和 y {}".format(np.shape(train_x[0:Ntrain]), np.shape(train_y[0:Ntrain])))
print("The dimension of the testing data: x {} 和 y {}".format(np.shape(train_x[Ntrain:]), np.shape(train_y[Ntrain:])), "\n")
return train_x[0:Ntrain], train_y[0:Ntrain], train_x[Ntrain:], train_y[Ntrain:]
Ntrain = 200 # the size of the training dataset
Ntest = 100 # the size of the testing dataset
boundary_gap = 0.5 # the gap between two classes
seed_data = 2 # fixed seed
# generate a new dataset
train_x, train_y, test_x, test_y = circle_data_point_generator(Ntrain, Ntest, boundary_gap, seed_data)
encoding="angle_encoding"
num_qubit=2
dimension=2
train_x=SimpleDataset(dimension).encode(train_x,encoding,num_qubit)
test_x=SimpleDataset(dimension).encode(test_x,encoding,num_qubit)
print(train_x[0])
print(test_x[0])
::
"""
def __init__(self, dimension):
r""" 构造函数
Args:
dimension (int): 编码数据的维度。
"""
Dataset.__init__(self)
self.dimension = dimension
return
def encode(self, feature, encoding, num_qubits, return_state=True, full_return=False):
r""" 进行编码
Args:
feature (list/ndarray): 编码的特征,每一个分量都是一个 ndarray 的特征向量
encoding (str): 编码方法
num_qubits (int): 编码的量子比特数目
return_state (bool): 是否返回量子态
Returns:
tuple: 包含如下元素:
- quantum_states (ndarray): 量子态,只有 ``full_return==True`` 或者 ``return_state==True`` 的时候会返回
- quantum_circuits (list): 所有特征编码的电路,只有 ``full_return==False`` 或者 ``return_state==True`` 的时候会返回
- origin_feature (ndarray): 经过类别过滤之后的所有特征,并未编码为量子态,只有 ``return_state==True`` 的时候会返回
- feature (ndarray): ``origin_feature`` 经过了补零之后的特征, ``quantum_states`` 就是将 ``feature`` 编码之后的结果。 只有 ``return_state==True`` 的时候会返回
"""
assert num_qubits > 0
if encoding in [IQP_ENCODING, COMPLEX_ENTANGLED_ENCODING, REAL_ENTANGLED_ENCODING,
LINEAR_ENTANGLED_ENCODING]:
assert num_qubits > 1
if type(feature) == np.ndarray:
self.feature = list(feature)
elif type(feature) is list:
self.feature = feature
else:
raise Exception("invalid type of feature")
self.origin_feature = np.array(feature)
# The first step, calculate ``self.can_describe_dimension``, and judge whether the qubit number is small
if encoding == AMPLITUDE_ENCODING: # amplitude encoding, encoding 2^N-dimension feature
self.can_describe_dimension = 2 ** num_qubits
# For these three kinds of entanglement encoding: lay these parameters block by block.
elif encoding == LINEAR_ENTANGLED_ENCODING:
one_block_param = 2 * num_qubits
self.can_describe_dimension = math.ceil(self.dimension / one_block_param) * one_block_param
elif encoding in [REAL_ENTANGLED_ENCODING, IQP_ENCODING, ANGLE_ENCODING]:
one_block_param = 1 * num_qubits
self.can_describe_dimension = math.ceil(self.dimension / one_block_param) * one_block_param
elif encoding in [COMPLEX_ENTANGLED_ENCODING, PAULI_ROTATION_ENCODING]:
one_block_param = 3 * num_qubits
self.can_describe_dimension = math.ceil(self.dimension / one_block_param) * one_block_param
else:
raise Exception("Invalid encoding methods!")
if self.can_describe_dimension < self.dimension:
raise Exception("The qubit number is not enough to encode the features.")
# 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] = 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)
self.quantum_states, self.quantum_circuits = self.data2circuit(
self.feature, encoding, num_qubits, self.can_describe_dimension, False, # split_circuit=False
return_state)
self.feature = np.array(self.feature)
self.quantum_states = np.array(self.quantum_states)
if full_return:
return self.quantum_states, self.quantum_circuits, self.origin_feature, self.feature
else:
if return_state:
return self.quantum_states
else:
return self.quantum_circuits
class Iris(SimpleDataset):
r""" Iris 数据集
Attributes:
quantum_states (ndarray): 经过类别过滤之后的所有特征经编码形成的量子态
quantum_circuits (list): 所有特征编码的电路
origin_feature (ndarray): 经过类别过滤之后的所有特征,并未编码为量子态
feature (ndarray): ``origin_feature`` 经过了补零之后的特征, ``quantum_states`` 就是将 ``feature`` 编码之后的结果
target (ndarray): 经过类别过滤之后的所有标签
train_x (paddle.tensor): 从 ``quantum_states`` 中选出的训练集
test_x (paddle.tensor): 从 ``quantum_states`` 中选出的测试集
train_circuits (list): 对应于 ``train_x`` 的编码电路
test_circuits (list): 对应于 ``test_x`` 的编码电路
origin_train_x (ndarray): 和 ``train_x`` 对应的经典数据
origin_test_x (ndarray): 和 ``test_x`` 对应的经典数据
train_y (ndarray): 对应于 ``train_x`` 的标签
test_y (ndarray): 对应于 ``test_x`` 的标签
代码示例:
.. code-block:: python
from paddle_quantum.dataset import Iris
test_rate=0.2
qubit_num=4
# Get Iris data, select two classes 0,1, and encode the data into four qubits using angle coding and return the quantum state.
# The proportion of the test set is 0.2.
iris =Iris (encoding='angle_encoding', num_qubits=qubit_num, test_rate=test_rate,classes=[0,1], return_state=True)
# Get the features and labels of the classical Iris dataset
origin_feature=iris.origin_feature # ndarray
origin_target=iris.target
# Gets the quantum states and labels of the training and test datasets
train_x, train_y = iris.train_x, iris.train_y # paddle.tensor, ndarray
test_x, test_y = iris.test_x, iris.test_y
testing_data_num=len(test_y)
training_data_num=len(train_y)
print(training_data_num)
print(testing_data_num)
"""
def __init__(self, encoding, num_qubits, classes, test_rate=0.2, need_relabel=True, return_state=True):
r""" 构造函数
Args:
encoding (str): ``"angle_encoding"`` 表示角度编码,一个量子比特编码一个旋转门; ``"amplitude_encoding"`` 表示振幅编码;
``"pauli_rotation_encoding"`` 表示SU(3)的角度编码;还有 ``"linear_entangled_encoding"`` 、
``"real_entangled_encoding"`` 、 ``"complex_entangled_encoding"`` 三种纠缠编码和 ``"IQP_encoding"`` 编码
num_qubits (int): 量子比特数目
classes (list): 用列表给出需要的类别,类别用数字标签表示,不支持传入名字
test_rate (float): 测试集的占比
need_relabel (bool): 将原有类别按照顺序重标记为 0、1、2 等新的名字,比如传入 ``[1,2]`` ,重标记之后变为 ``[0,1]`` ,主要用于二分类
return_state (bool): 是否返回量子态,如果是 ``False`` 返回量子电路
"""
SimpleDataset.__init__(self, dimension=4)
# Download data from scikit-learn
iris = datasets.load_iris()
self.dimension = 4 # dimension of Iris dataset
feature, self.target = self.filter_class(iris.data, iris.target, classes, -1,
need_relabel) # here -1 means all data
self.target = np.array(self.target)
# Start to encode
self.quantum_states, self.quantum_circuits, self.origin_feature, self.feature = \
self.encode(feature, encoding, num_qubits, return_state, True)
# Divide training and testing dataset
seed = int(time.time())
self.train_x, self.test_x, self.train_y, self.test_y = \
train_test_split(self.quantum_states, self.target, test_size=test_rate,
random_state=seed)
self.train_circuits, self.test_circuits, temp1, temp2 = \
train_test_split(self.quantum_circuits, self.target, test_size=test_rate,
random_state=seed)
self.origin_train_x, self.origin_test_x, temp1, temp2 = \
train_test_split(self.origin_feature, self.target, test_size=test_rate,
random_state=seed)
if return_state:
self.train_x = paddle.to_tensor(self.train_x)
self.test_x = paddle.to_tensor(self.test_x)
class BreastCancer(SimpleDataset):
r"""BreastCancer 数据集,569 组数据 30 维,只有两类。
Attributes:
quantum_states (ndarray): 经过类别过滤之后的所有特征经编码形成的量子态
quantum_circuits (list): 所有特征编码的电路
origin_feature (ndarray): 经过类别过滤之后的所有特征,并未编码为量子态
feature (ndarray): ``origin_feature`` 经过了补零之后的特征, ``quantum_states`` 就是将 ``feature`` 编码之后的结果
target (ndarray): 经过类别过滤之后的所有标签
train_x (paddle.tensor): 从 ``quantum_states`` 中选出的训练集
test_x (paddle.tensor): 从 ``quantum_states`` 中选出的测试集
train_circuits (list): 对应于 ``train_x`` 的编码电路
test_circuits (list): 对应于 ``test_x`` 的编码电路
origin_train_x (ndarray): 和 ``train_x`` 对应的经典数据
origin_test_x (ndarray): 和 ``test_x`` 对应的经典数据
train_y (ndarray): 对应于 ``train_x`` 的标签
test_y (ndarray): 对应于 ``test_x`` 的标签
代码示例:
.. code-block:: python
from paddle_quantum.dataset import BreastCancer
test_rate = 0.2
qubit_num = 4
# Get BreastCancer data, select two classes 0,1, and encode the data into four qubits using angle coding and return the quantum state.
# The proportion of the test set is 0.2.
breast_cancer =BreastCancer(encoding='angle_encoding', num_qubits=qubit_num, test_rate=test_rate, return_state=True)
# Get the features and labels of the classical BreastCancer dataset
origin_feature=breast_cancer.origin_feature # ndarray
origin_target=breast_cancer.target
# Gets the quantum states and labels of the training and test datasets
train_x, train_y = breast_cancer.train_x, breast_cancer.train_y # paddle.tensor, ndarray
test_x, test_y = breast_cancer.test_x, breast_cancer.test_y
testing_data_num=len(test_y)
training_data_num=len(train_y)
print(training_data_num)
print(testing_data_num)
"""
def __init__(self, encoding, num_qubits, test_rate=0.2, return_state=True):
r"""构造函数
Args:
encoding (str): ``"angle_encoding"`` 表示角度编码,一个量子比特编码一个旋转门; ``"amplitude_encoding"`` 表示振幅编码;
``"pauli_rotation_encoding"`` 表示SU(3)的角度编码;还有 ``"linear_entangled_encoding"`` 、
``"real_entangled_encoding"`` 、 ``"complex_entangled_encoding"`` 三种纠缠编码和 ``"IQP_encoding"`` 编码
num_qubits (int): 量子比特数目
test_rate (float): 测试集的占比
return_state (bool): 是否返回量子态,如果是 ``False`` 返回量子电路
"""
SimpleDataset.__init__(self, dimension=30) # The dimension is 30
self.dimension = 30
# Download data from scikit-learn
breast_cancer = datasets.load_breast_cancer()
feature = breast_cancer["data"]
self.target = breast_cancer["target"]
self.target = np.array(self.target)
# Start to encode
self.quantum_states, self.quantum_circuits, self.origin_feature, self.feature = \
self.encode(feature, encoding, num_qubits, return_state, True)
# Divide training and testing dataset
seed = int(time.time())
self.train_x, self.test_x, self.train_y, self.test_y = \
train_test_split(self.quantum_states, self.target, test_size=test_rate,
random_state=seed)
self.train_circuits, self.test_circuits, temp1, temp2 = \
train_test_split(self.quantum_circuits, self.target, test_size=test_rate,
random_state=seed)
self.origin_train_x, self.origin_test_x, temp1, temp2 = \
train_test_split(self.origin_feature, self.target, test_size=test_rate,
random_state=seed)
if return_state:
self.train_x = paddle.to_tensor(self.train_x)
self.test_x = paddle.to_tensor(self.test_x)
# Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
梯度分析工具模块
"""
import numpy as np
import paddle
from paddle import reshape
from random import choice
from tqdm import tqdm
import matplotlib.pyplot as plt
__all__ = [
"StateNet",
"show_gradient",
"random_sample",
"random_sample_supervised",
"plot_loss_grad",
"plot_supervised_loss_grad",
"plot_distribution"
]
class StateNet(paddle.nn.Layer):
r"""定义用于量子机器学习的量子神经网络模型
用户可以通过实例化该类定义自己的量子神经网络模型。
"""
def __init__(self, shape, dtype='float64'):
r"""构造函数,用于实例化一个 ``StateNet`` 对象
Args:
shape (paddle.Tensor): 表示传入的量子电路中的需要被优化的参数个数
"""
super(StateNet, self).__init__()
self.theta = self.create_parameter(shape=shape,
default_initializer=paddle.nn.initializer.Uniform(low=0.0, high=2*np.pi),
dtype=dtype, is_bias=False)
def forward(self, circuit, loss_func, *args):
r"""用于更新电路参数并计算该量子神经网络的损失值。
Args:
circuit (UAnsatz): 表示传入的参数化量子电路,即要训练的量子神经网络
loss_func (function): 表示计算该量子神经网络损失值的函数
*args (list): 表示用于损失函数计算的额外参数列表
Note:
这里的 ``loss_func`` 是一个用户自定义的计算损失值的函数,参数为电路和一个可变参数列表。
Returns:
tuple: 包含如下两个元素:
- loss (paddle.Tensor): 表示该量子神经网络损失值
- circuit (UAnsatz): 更新参数后的量子电路
"""
circuit.update_param(self.theta)
circuit.run_state_vector()
loss = loss_func(circuit, *args)
return loss, circuit
def show_gradient(circuit, loss_func, ITR, LR, *args):
r"""计算量子神经网络中各可变参数的梯度值和损失函数值
Args:
circuit (UAnsatz): 表示传入的参数化量子电路,即要训练的量子神经网络
loss_func (function): 表示计算该量子神经网络损失值的函数
ITR (int): 表示训练的次数
LR (float): 表示学习训练的速率
*args (list): 表示用于损失函数计算的额外参数列表
Returns:
tuple: 包含如下两个元素:
- loss_list (list): 表示损失函数值随训练次数变化的列表
- grad_list(list): 表示各参数梯度随训练次变化的列表
"""
grad_list = []
loss_list = []
shape = paddle.shape(circuit.get_param())
net = StateNet(shape=shape)
opt = paddle.optimizer.Adam(learning_rate=LR, parameters=net.parameters())
pbar = tqdm(
desc="Training: ", total=ITR, ncols=100, ascii=True
)
for itr in range(ITR):
pbar.update(1)
loss, cir = net(circuit, loss_func, *args)
loss.backward()
grad = net.theta.grad.numpy()
grad_list.append(grad)
loss_list.append(loss.numpy()[0])
opt.minimize(loss)
opt.clear_grad()
pbar.close()
return loss_list, grad_list
def plot_distribution(grad):
r"""根据输入的梯度的列表,画出梯度的分布图
Args:
grad (np.array): 表示量子神经网络某参数的梯度列表
"""
grad = np.abs(grad)
grad_list = [0, 0, 0, 0, 0]
x = ['<0.0001', ' (0.0001,0.001)', '(0.001,0.01)', '(0.01,0.1)', '>0.1']
for g in grad:
if g > 0.1:
grad_list[4] += 1
elif g > 0.01:
grad_list[3] += 1
elif g > 0.001:
grad_list[2] += 1
elif g > 0.0001:
grad_list[1] += 1
else:
grad_list[0] += 1
grad_list = np.array(grad_list) / len(grad)
plt.figure()
plt.bar(x, grad_list, width=0.5)
plt.title('The gradient distribution of variables')
plt.ylabel('ratio')
plt.show()
def random_sample(circuit, loss_func, sample_num, *args, mode='single', if_plot=True, param=0):
r"""表示对模型进行随机采样,根据不同的计算模式,获得对应的平均值和方差
Args:
circuit (UAnsatz): 表示传入的参数化量子电路,即要训练的量子神经网络
loss_func (function): 表示计算该量子神经网络损失值的函数
sample_num (int): 表示随机采样的次数
mode (string): 表示随机采样后的计算模式,默认为 'single'
if_plot(boolean): 表示是否对梯度进行画图表示
param (int): 表示 ``Single`` 模式中对第几个参数进行画图,默认为第一个参数
*args (list): 表示用于损失函数计算的额外参数列表
Note:
在本函数中提供了三种计算模式,``mode`` 分别可以选择 ``'single'``, ``'max'``, 以及 ``'random'``
- mode='single': 表示计算电路中的每个可变参数梯度的平均值和方差
- mode='max': 表示对电路中每轮采样的所有参数梯度的最大值求平均值和方差
- mode='random': 表示对电路中每轮采样的所有参数随机取一个梯度,求平均值和方差
Returns:
tuple: 包含如下两个元素:
- loss_list (list): 表示多次采样后损失函数值的列表
- grad_list(list): 表示多次采样后各参数梯度的列表
"""
loss_list, grad_list = [], []
pbar = tqdm(
desc="Sampling: ", total=sample_num, ncols=100, ascii=True
)
for itr in range(sample_num):
pbar.update(1)
shape = paddle.shape(circuit.get_param())
net = StateNet(shape=shape)
loss, cir = net(circuit, loss_func, *args)
loss.backward()
grad = net.theta.grad.numpy()
loss_list.append(loss.numpy()[0])
grad_list.append(grad)
pbar.close()
if mode == 'single':
grad_list = np.array(grad_list)
grad_list = grad_list.transpose()
grad_variance_list = []
grad_mean_list = []
for idx in range(len(grad_list)):
grad_variance_list.append(np.var(grad_list[idx]))
grad_mean_list.append(np.mean(grad_list[idx]))
print("Mean of gradient for all parameters: ")
for i in range(len(grad_mean_list)):
print("theta", i+1, ": ", grad_mean_list[i])
print("Variance of gradient for all parameters: ")
for i in range(len(grad_variance_list)):
print("theta", i+1, ": ", grad_variance_list[i])
if if_plot:
plot_distribution(grad_list[param])
return grad_mean_list, grad_variance_list
if mode == 'max':
max_grad_list = []
for idx in range(len(grad_list)):
max_grad_list.append(np.max(np.abs(grad_list[idx])))
print("Mean of max gradient")
print(np.mean(max_grad_list))
print("Variance of max gradient")
print(np.var(max_grad_list))
if if_plot:
plot_distribution(max_grad_list)
return np.mean(max_grad_list), np.var(max_grad_list)
if mode == 'random':
random_grad_list = []
for idx in range(len(grad_list)):
random_grad = choice(grad_list[idx])
random_grad_list.append(random_grad)
print("Mean of random gradient")
print(np.mean(random_grad_list))
print("Variance of random gradient")
print(np.var(random_grad_list))
if if_plot:
plot_distribution(random_grad_list)
return np.mean(random_grad_list), np.var(random_grad_list)
return loss_list, grad_list
def plot_loss_grad(circuit, loss_func, ITR, LR, *args):
r"""绘制损失值和梯度随训练次数变化的图
Args:
circuit (UAnsatz): 表示传入的参数化量子电路,即要训练的量子神经网络
loss_func (function): 表示计算该量子神经网络损失值的函数
ITR (int): 表示训练的次数
LR (float): 表示学习训练的速率
*args (list): 表示用于损失函数计算的额外参数列表
"""
loss, grad = show_gradient(circuit, loss_func, ITR, LR, *args)
plt.xlabel(r"Iteration")
plt.ylabel(r"Loss")
plt.plot(range(1, ITR+1), loss, 'r', label='loss')
plt.legend()
plt.show()
max_grad = [np.max(np.abs(i)) for i in grad]
plt.xlabel(r"Iteration")
plt.ylabel(r"Gradient")
plt.plot(range(1, ITR+1), max_grad, 'b', label='gradient')
plt.legend()
plt.show()
def plot_supervised_loss_grad(circuit, loss_func, N, EPOCH, LR, BATCH, TRAIN_X, TRAIN_Y, *args):
r"""绘制监督学习中损失值和梯度随训练次数变化的图
Args:
circuit (UAnsatz): 表示传入的参数化量子电路,即要训练的量子神经网络
loss_func (function): 表示计算该量子神经网络损失值的函数
N (int): 表示量子比特的数量
EPOCH (int): 表示训练的轮数
LR (float): 表示学习训练的速率
BATCH (int): 表示训练时 batch 的大小
TRAIN_X (paddle.Tensor): 表示训练数据集
TRAIN_Y (list): 表示训练数据集的标签
*args (list): 表示用于损失函数计算的额外参数列表
Returns:
tuple: 包含如下两个元素:
- loss_list (list): 表示多次训练的损失函数值列表
- grad_list(list): 表示多次训练后各参数梯度的列表
"""
grad_list = []
loss_list = []
if type(TRAIN_X) != paddle.Tensor:
raise Exception("Training data should be paddle.Tensor type")
shape = paddle.shape(circuit.get_param())
net = StateNet(shape=shape)
opt = paddle.optimizer.Adam(learning_rate=LR, parameters=net.parameters())
for ep in range(EPOCH):
for itr in range(len(TRAIN_X)//BATCH):
input_state = TRAIN_X[itr*BATCH:(itr+1)*BATCH]
input_state = reshape(input_state, [-1, 1, 2**N])
label = TRAIN_Y[itr * BATCH:(itr + 1) * BATCH]
loss, circuit = net(circuit, loss_func, input_state, label)
loss.backward()
grad = net.theta.grad.numpy()
grad_list.append(grad)
loss_list.append(loss.numpy()[0])
opt.minimize(loss)
opt.clear_grad()
max_grad = [np.max(np.abs(i)) for i in grad_list]
plt.xlabel(r"Iteration")
plt.ylabel(r"Loss")
plt.plot(range(1, EPOCH*len(TRAIN_X)//BATCH+1), loss_list, 'r', label='loss')
plt.legend()
plt.show()
plt.xlabel(r"Iteration")
plt.ylabel(r"Gradient")
plt.plot(range(1, EPOCH*len(TRAIN_X)//BATCH+1), max_grad, 'b', label='gradient')
plt.legend()
plt.show()
return loss_list, grad_list
def random_sample_supervised(circuit, loss_func, N, sample_num, BATCH, TRAIN_X, TRAIN_Y, *args, mode='single', if_plot=True, param=0):
r"""表示对监督学习模型进行随机采样,根据不同的计算模式,获得对应的平均值和方差
Args:
circuit (UAnsatz): 表示传入的参数化量子电路,即要训练的量子神经网络
loss_func (function): 表示计算该量子神经网络损失值的函数
N (int): 表示量子比特的数量
sample_num (int): 表示随机采样的次数
BATCH (int): 表示训练时 batch 的大小
TRAIN_X (paddle.Tensor): 表示训练数据集
TRAIN_Y (list): 表示训练数据集的标签
mode (string): 表示随机采样后的计算模式,默认为 'single'
if_plot(boolean): 表示是否对梯度进行画图表示
param (int): 表示 ``Single`` 模式中对第几个参数进行画图,默认为第一个参数
*args (list): 表示用于损失函数计算的额外参数列表
Note:
在本函数中提供了三种计算模式,``mode`` 分别可以选择 ``'single'``, ``'max'``, 以及 ``'random'``
- mode='single': 表示计算电路中的每个可变参数梯度的平均值和方差
- mode='max': 表示对电路中所有参数梯度的最大值求平均值和方差
- mode='random': 表示随机对电路中采样的所有参数随机取一个梯度,求平均值和方差
Returns:
tuple: 包含如下两个元素:
- loss_list (list): 表示多次采样后损失函数值的列表
- grad_list(list): 表示多次采样后各参数梯度的列表
"""
grad_list = []
loss_list = []
input_state = TRAIN_X[0:BATCH]
input_state = reshape(input_state, [-1, 1, 2**N])
label = TRAIN_Y[0: BATCH]
if type(TRAIN_X) != paddle.Tensor:
raise Exception("Training data should be paddle.Tensor type")
label = TRAIN_Y[0: BATCH]
pbar = tqdm(
desc="Sampling: ", total=sample_num, ncols=100, ascii=True
)
for idx in range(sample_num):
pbar.update(1)
shape = paddle.shape(circuit.get_param())
net = StateNet(shape=shape)
loss, circuit = net(circuit, loss_func, input_state, label)
loss.backward()
grad = net.theta.grad.numpy()
grad_list.append(grad)
loss_list.append(loss.numpy()[0])
pbar.close()
if mode == 'single':
grad_list = np.array(grad_list)
grad_list = grad_list.transpose()
grad_variance_list = []
grad_mean_list = []
for idx in range(len(grad_list)):
grad_variance_list.append(np.var(grad_list[idx]))
grad_mean_list.append(np.mean(grad_list[idx]))
print("Mean of gradient for all parameters: ")
for i in range(len(grad_mean_list)):
print("theta", i+1, ": ", grad_mean_list[i])
print("Variance of gradient for all parameters: ")
for i in range(len(grad_variance_list)):
print("theta", i+1, ": ", grad_variance_list[i])
if if_plot:
plot_distribution(grad_list[param])
return grad_mean_list, grad_variance_list
if mode == 'max':
max_grad_list = []
for idx in range(len(grad_list)):
max_grad_list.append(np.max(np.abs(grad_list[idx])))
print("Mean of max gradient")
print(np.mean(max_grad_list))
print("Variance of max gradient")
print(np.var(max_grad_list))
if if_plot:
plot_distribution(max_grad_list)
return np.mean(max_grad_list), np.var(max_grad_list)
if mode == 'random':
random_grad_list = []
for idx in range(len(grad_list)):
random_grad = choice(grad_list[idx])
random_grad_list.append(random_grad)
print("Mean of random gradient")
print(np.mean(random_grad_list))
print("Variance of random gradient")
print(np.var(random_grad_list))
if if_plot:
plot_distribution(random_grad_list)
return np.mean(random_grad_list), np.var(random_grad_list)
return loss_list, grad_list
...@@ -68,7 +68,7 @@ class LoccStatus(object): ...@@ -68,7 +68,7 @@ class LoccStatus(object):
return self.measured_result return self.measured_result
else: else:
raise ValueError("too many values to unpack (expected 3)") raise ValueError("too many values to unpack (expected 3)")
def __repr__(self): def __repr__(self):
return f"state: {self.state.numpy()}\nprob: {self.prob.numpy()[0]}\nmeasured_result: {self.measured_result}" return f"state: {self.state.numpy()}\nprob: {self.prob.numpy()[0]}\nmeasured_result: {self.measured_result}"
......
...@@ -967,9 +967,12 @@ def print_progress(current_progress, progress_name, track=True): ...@@ -967,9 +967,12 @@ def print_progress(current_progress, progress_name, track=True):
assert 0 <= current_progress <= 1, "'current_progress' must be between 0 and 1" assert 0 <= current_progress <= 1, "'current_progress' must be between 0 and 1"
assert isinstance(track, bool), "'track' must be a bool." assert isinstance(track, bool), "'track' must be a bool."
if track: if track:
print("\r" + f"{progress_name.ljust(30)}" print(
f"|{'■' * int(50 * current_progress):{50}s}| " "\r"
f"\033[94m {'{:6.2f}'.format(100 * current_progress)}% \033[0m ", flush=True, end="") f"{progress_name.ljust(30)}"
f"|{'■' * int(50 * current_progress):{50}s}| "
f"\033[94m {'{:6.2f}'.format(100 * current_progress)}% \033[0m ", flush=True, end=""
)
if current_progress == 1: if current_progress == 1:
print(" (Done)") print(" (Done)")
......
...@@ -19,6 +19,7 @@ CG optimizer ...@@ -19,6 +19,7 @@ CG optimizer
from scipy import optimize from scipy import optimize
from .custom_optimizer import CustomOptimizer from .custom_optimizer import CustomOptimizer
class ConjugateGradient(CustomOptimizer): class ConjugateGradient(CustomOptimizer):
r"""ConjugateGradient Optimizer r"""ConjugateGradient Optimizer
...@@ -57,6 +58,6 @@ class ConjugateGradient(CustomOptimizer): ...@@ -57,6 +58,6 @@ class ConjugateGradient(CustomOptimizer):
method='CG', method='CG',
jac=self.grad_func, jac=self.grad_func,
options={'maxiter': iterations}, options={'maxiter': iterations},
callback=lambda xk: print('loss: ', (self.loss_func(xk, self.cir, self.hamiltonian, self.shots))) callback=lambda xk: print('loss: ', self.loss_func(xk, self.cir, self.hamiltonian, self.shots))
) )
print(opt_res.message) print(opt_res.message)
...@@ -19,6 +19,7 @@ Newton-CG optimizer ...@@ -19,6 +19,7 @@ Newton-CG optimizer
from scipy import optimize from scipy import optimize
from .custom_optimizer import CustomOptimizer from .custom_optimizer import CustomOptimizer
class NewtonCG(CustomOptimizer): class NewtonCG(CustomOptimizer):
r"""Newton-CG Optimizer r"""Newton-CG Optimizer
...@@ -57,6 +58,6 @@ class NewtonCG(CustomOptimizer): ...@@ -57,6 +58,6 @@ class NewtonCG(CustomOptimizer):
method='Newton-CG', method='Newton-CG',
jac=self.grad_func, jac=self.grad_func,
options={'maxiter': iterations}, options={'maxiter': iterations},
callback=lambda xk: print('loss: ', (self.loss_func(xk, self.cir, self.hamiltonian, self.shots))) callback=lambda xk: print('loss: ', self.loss_func(xk, self.cir, self.hamiltonian, self.shots))
) )
print(opt_res.message) print(opt_res.message)
...@@ -19,6 +19,7 @@ Powell optimizer ...@@ -19,6 +19,7 @@ Powell optimizer
from scipy import optimize from scipy import optimize
from .custom_optimizer import CustomOptimizer from .custom_optimizer import CustomOptimizer
class Powell(CustomOptimizer): class Powell(CustomOptimizer):
r"""Powell Optimizer r"""Powell Optimizer
...@@ -54,5 +55,5 @@ class Powell(CustomOptimizer): ...@@ -54,5 +55,5 @@ class Powell(CustomOptimizer):
method='Powell', method='Powell',
options={'maxiter': iterations}, options={'maxiter': iterations},
callback=lambda xk: print('loss: ', self.loss_func(xk, self.cir, self.hamiltonian, self.shots)) callback=lambda xk: print('loss: ', self.loss_func(xk, self.cir, self.hamiltonian, self.shots))
) )
print(opt_res.message) print(opt_res.message)
...@@ -19,6 +19,7 @@ SLSQP optimizer ...@@ -19,6 +19,7 @@ SLSQP optimizer
from scipy import optimize from scipy import optimize
from .custom_optimizer import CustomOptimizer from .custom_optimizer import CustomOptimizer
class SLSQP(CustomOptimizer): class SLSQP(CustomOptimizer):
r"""SLSQP Optimizer r"""SLSQP Optimizer
...@@ -53,5 +54,5 @@ class SLSQP(CustomOptimizer): ...@@ -53,5 +54,5 @@ class SLSQP(CustomOptimizer):
method='SLSQP', method='SLSQP',
options={'maxiter': iterations}, options={'maxiter': iterations},
callback=lambda xk: print('loss: ', self.loss_func(xk, self.cir, self.hamiltonian, self.shots)) callback=lambda xk: print('loss: ', self.loss_func(xk, self.cir, self.hamiltonian, self.shots))
) )
print(opt_res.message) print(opt_res.message)
# Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
量桨平台的量子化学模块
"""
from .qmodel import QModel
from . import ansatz
from .run import run_chem
from .qchem import *
import platform
import warnings
__all__ = [
"run_chem",
"QModel",
"ansatz",
"geometry",
"get_molecular_data",
"active_space",
# forward compatible with original qchem module
"fermionic_hamiltonian",
"spin_hamiltonian"
]
if platform.system() == "Windows":
warning_msg = ("Currently, Windows' users can't use 'hartree fock' ansatz "
"for ground state energy calculation in `run_chem`, "
"since it depends on pyscf, which is not available on Windows. "
"We will work it out in the near future, sorry for the inconvenience.")
warnings.warn(message=warning_msg)
# Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
r"""
化学模块的 ansatz
"""
from .hardware_efficient import HardwareEfficientModel
from .rhf import RestrictHartreeFockModel
# Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Hardware efficient ansatz 量子电路,以
`Hardware-efficient variational quantum eigensolver
for small molecules and quantum magnets` 方式构建。
具体细节可以参见 https://arxiv.org/abs/1704.05018
该模块依赖于
- paddlepaddle
- paddle_quantum
- ../layers
- ../qmodel
"""
import paddle
from paddle import nn
from paddle_quantum.circuit import UAnsatz
from ..qmodel import QModel
from .. import layers
class HardwareEfficientModel(QModel):
r"""面向硬件的量子线路。
Args:
num_qubit (int): 量子线路的量子比特数量。
circuit_depth (int): Cross resonance 和 Euler 转动层的数量。
"""
def __init__(self, num_qubit: int, circuit_depth: int) -> None:
super().__init__(num_qubit)
mid_layers = []
for i in range(circuit_depth):
mid_layers.append(layers.CrossResonanceLayer(num_qubit))
mid_layers.append(layers.EulerRotationLayer(num_qubit))
self.model = nn.Sequential(
layers.RotationLayer(num_qubit, "X"),
layers.RotationLayer(num_qubit, "Z"),
*mid_layers,
)
def forward(
self,
state: "paddle.Tensor[paddle.complex128]"
) -> "paddle.Tensor[paddle.complex128]":
r"""运行量子电路
Args:
state (paddle.Tensor[paddle.complex128]): 传入量子线路的量子态。
Returns:
paddle.Tensor[paddle.complex128]: 运行电路后的量子态
"""
out = self.model(state)
cir0 = UAnsatz(self._n_qubit)
for subcir in self.model:
cir0 += subcir.circuit
self._circuit = cir0
return out
# Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Restrict Hartree Fock 模块
"""
from collections import OrderedDict
from copy import deepcopy
import numpy as np
import paddle
from paddle.nn import initializer
from paddle_quantum.circuit import UAnsatz
from ..linalg import givens_decomposition, parameters_to_givens_matrix2
from ..qmodel import QModel
from .. import functional
class _MakeGivensMatrix(paddle.autograd.PyLayer):
r"""Construct Givens rotation matrix G from parameters \theta and \phi.
.. math::
G[j-1,j-1] = \cos(\theta)
G[j,j] = \cos(\theta)
G[j-1,j] = -\phi\sin(\theta)
G[j,j-1] = \phi\sin(\theta)
We define this function since paddle doesn't fully support differentiate over
copy and slice operation, e.g. A[i,j] = \theta, where \theta is the parameter
to be differentiated.
"""
@staticmethod
def forward(ctx, theta: paddle.Tensor, phi: paddle.Tensor, j: int, n: int):
G = parameters_to_givens_matrix2(theta, phi, j, n)
ctx.saved_index = j
ctx.save_for_backward(theta, phi)
return G
@staticmethod
def backward(ctx, dG):
j = ctx.saved_index
theta, phi = ctx.saved_tensor()
dtheta = (-1.0 * (dG[j - 1, j - 1] + dG[j, j]) * paddle.sin(theta)
+ (dG[j, j - 1] - dG[j - 1, j]) * phi * paddle.cos(theta))
return dtheta, None
class RestrictHartreeFockModel(QModel):
r"""限制性 Hartree Fock (RHF) 波函数的量子线路。
Args:
num_qubits (int): RHF 计算中需要使用的量子比特数量。
n_electrons (int): 待模拟的量子化学系统中的电子数量。
onebody (paddle.Tensor(dtype=paddle.float64)): 经过 L\"owdin 正交化之后的单体积分。
"""
def __init__(
self,
num_qubits: int,
n_electrons: int,
onebody: paddle.Tensor
) -> None:
super().__init__(num_qubits)
self.nocc = n_electrons // 2
self.norb = num_qubits // 2
self.nvir = self.norb - self.nocc
givens_angles = self.get_init_givens_angles(onebody)
models = []
for ij, (theta, phi) in givens_angles.items():
models.append((ij, _GivensBlock(self.n_qubit, -theta, phi)))
self.models = paddle.nn.Sequential(*models)
def get_init_givens_angles(self, onebody: paddle.Tensor) -> OrderedDict:
r"""利用单体积分来初始化 Givens 旋转的角度。
Args:
onebody (paddle.Tensor): 经过 L\"owdin 正交化之后的单体积分。
Returns:
OrderedDict
"""
assert type(onebody) == paddle.Tensor, "The onebody integral must be a paddle.Tensor."
_, U = np.linalg.eigh(onebody.numpy())
U_tensor = paddle.to_tensor(U)
return givens_decomposition(U_tensor)
def forward(self, state: paddle.Tensor) -> paddle.Tensor:
r"""运行量子电路
Args:
state (paddle.Tensor[paddle.complex128]): 传入量子线路的量子态矢量。
Returns:
paddle.Tensor[paddle.complex128]: 运行电路后的量子态
"""
s = deepcopy(state)
self._circuit = UAnsatz(self.n_qubit)
for ij, givens_ops in self.models.named_children():
i, j = [int(p) for p in ij.split(",")]
s = givens_ops(s, 2 * i, 2 * j)
self._circuit += givens_ops.circuit
s = givens_ops(s, 2 * i + 1, 2 * j + 1)
self._circuit += givens_ops.circuit
return s
def single_particle_U(self):
r"""获取 Hartree Fock 轨道旋转矩阵
Returns:
paddle.Tensor, Hartree Fock 轨道旋转矩阵,:math:`n_{orbitals}\times n_{occ}`
"""
self.register_buffer("_U", paddle.eye(int(self.norb), dtype=paddle.float64))
for ij, givens_ops in self.models.named_children():
j = int(ij.split(",")[1])
self._U = givens_ops.single_particle_U(j, self.norb) @ self._U
return self._U[:, :self.nocc]
# !/usr/bin/env python3
# Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
用于构建量子电路层的函数操作。
该模块依赖于 paddlepaddle 和 paddle_quantum
"""
import paddle
from paddle_quantum.circuit import UAnsatz
# Rotation layer function
def rot_layer(
cir: UAnsatz,
parameters: "paddle.Tensor[paddle.float64]",
gate_type: str
) -> UAnsatz:
r"""该函数用来在量子线路上添加一层单比特旋转门,"Rx", "Ry", "Rz"
Args:
cir (UAnsatz): 量子线路
parameters (paddle.Tensor[paddle.float64]): 旋转门的旋转角度
gate_type (str): "X", "Y" 和 "Z",例如:如果是 "Rx" 门,则添 "X"
Returns:
UAnsatz
"""
n_qubits = cir.n
assert n_qubits == len(parameters), \
"length of the parameters must equal the number of qubits"
for i in range(n_qubits):
if gate_type == "X":
cir.rx(parameters[i], i)
elif gate_type == "Y":
cir.ry(parameters[i], i)
elif gate_type == "Z":
cir.rz(parameters[i], i)
return cir
# Euler rotation gate function
def euler_rotation(
cir: UAnsatz,
which_qubit: int,
angles: "paddle.Tensor[paddle.float64]",
) -> UAnsatz:
r"""该函数定义了单比特的 Euler 旋转门(使用 ZXZ 规范)
.. math::
U(\theta,\phi,\gamma)=e^{-i\gamma/2\hat{Z}}e^{-i\phi/2\hat{X}}e^{-i\theta/2\hat{X}}.
Args:
cir (UAnsatz): 量子线路
which (int): Euler 旋转门作用的量子比特编号
angles (paddle.Tensor[paddle.float64]): Euler 角,存储顺序与 ZXZ 操作的顺序相反。
Returns:
UAnsatz
"""
cir.rz(angles[0], which_qubit)
cir.rx(angles[1], which_qubit)
cir.rz(angles[2], which_qubit)
return cir
# Euler rotation layer function
def euler_rotation_layer(
cir: UAnsatz,
parameters: "paddle.Tensor[paddle.float64]",
) -> UAnsatz:
r"""该函数会在给定的量子线路上添加一层 Euler 旋转门。
Args:
cir (UAnsatz): 量子线路。
parameters (paddle.Tensor[paddle.float64]): Euler 角参数集合。
"""
n_qubits = cir.n
assert len(
parameters) == 3 * n_qubits, "length of parameter should be 3 times of the number of qubits in the circuit."
for i in range(n_qubits):
cir = euler_rotation(cir, i, parameters[3 * i:3 * (i + 1)])
return cir
# Cross resonance gate function
def cross_resonance(
cir: UAnsatz,
ctrl_targ: "list[int]",
phase_angle: paddle.Tensor
) -> UAnsatz:
r"""该函数定义了一个双比特的 cross resonance (CR) 门。
.. math::
U(\theta) = \exp(-i\frac{\theta}{2}\hat{X}\otimes\hat{Z})
Args:
cir (UAnsatz): 量子线路。
ctrl_targ (list[int]): 控制比特和目标比特对应的比特编号。
phase_angle (paddle.Tensor[paddle.float64]): 旋转角度。
Returns:
UAnsatz
"""
cir.h(ctrl_targ[0])
cir.rzz(phase_angle, ctrl_targ)
cir.h(ctrl_targ[0])
return cir
# Cross resonance layer function
def cr_layer(
cir: UAnsatz,
parameters: "paddle.Tensor[paddle.float64]",
ctrl_qubit_index: "list[int]",
targ_qubit_index: "list[int]"
) -> UAnsatz:
"""该函数在给定线路上按照给定的控制和目标比特编号添加一层 cross resonance (CR) 门。
Args:
cir (UAnsatz): 量子线路。
parameters (paddle.Tensor[paddle.float64]): CR 门中的角度。
ctrl_qubit_index (list[int]): 控制比特序号。
targ_qubit_index (list[int]): 目标比特序号。
Returns:
UAnsatz
"""
assert len(parameters) == len(ctrl_qubit_index) and len(ctrl_qubit_index) == len(targ_qubit_index), \
"length of parameter must be the same as the number of cr gates"
for i, ct_index in enumerate(zip(ctrl_qubit_index, targ_qubit_index)):
cir = cross_resonance(cir, list(ct_index), parameters[i])
return cir
# Nearest neighbor Givens rotation gate function
def givens_rotation(
cir: UAnsatz,
theta: "paddle.Tensor[paddle.float64]",
q1_index: int,
q2_index: int
) -> UAnsatz:
r"""该函数定义了两个相邻比特之间的 Givens 旋转门。详细信息参见 https://arxiv.org/abs/1711.05395.
Note:
在 paddlequantum :math:`Ry(\theta)=e^{-i\frac{\theta}{2}\hat{Y}}`.
Args:
cir (UAnsatz): 量子线路。
theta (paddle.Tensor[paddle.float64]): 操作中 Ry 门的角度。
q1_index (int): 第一个 qubit 的编号。
q2_index (int): 第二个 qubit 的编号。
Returns:
UAnsatz
"""
cir.cnot([q2_index, q1_index])
cir.cry(-2 * theta, [q1_index, q2_index])
cir.cnot([q2_index, q1_index])
return cir
# !/usr/bin/env python3
# Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
量子电路层,该模块依赖于 paddlepaddle,paddle_quantum 和 math 包。
同时依赖于 qmodel 和 functional 模块。
"""
import math
import paddle
from paddle.nn import initializer
from paddle_quantum.circuit import UAnsatz
from .qmodel import QModel
from . import functional
# Rotation layer
class RotationLayer(QModel):
r"""单比特旋转门层。
Args:
num_qubits (int): 量子线路的量子比特数。
gate_type (str): 量子门的类型,"X", "Y" 和 "Z" 中的一个。
trainable (bool): 层中的角度参数是否可训练。
"""
def __init__(self, num_qubits: int, gate_type: str, trainable: bool = True):
super().__init__(num_qubits)
self._angle_attr = paddle.ParamAttr(
initializer=initializer.Uniform(0.0, 2*math.pi),
trainable=trainable
)
self.angles = self.create_parameter(
shape=[num_qubits],
attr=self._angle_attr,
dtype="float64"
)
self._gate_type = gate_type
def forward(
self,
state: "paddle.Tensor[paddle.complex128]"
) -> "paddle.Tensor[paddle.complex128]":
r"""获取运行后的量子态
Args:
state (paddle.Tensor[paddle.complex128, shape=[n]]): 送入电路的量子态
Returns:
paddle.Tensor[paddle.complex128, shape=[n]]: 运行电路后的量子态
"""
cir0 = UAnsatz(self._n_qubit)
self._circuit = functional.rot_layer(cir0, self.angles, self._gate_type)
return self.circuit.run_state_vector(state)
def extra_repr(self):
r"""额外表示
"""
return "gate={:s}, dtype={:s}".format(
self._gate_type,
self.angles.dtype.name)
# Euler rotation layer
class EulerRotationLayer(QModel):
r"""Euler 旋转门层。
Args:
num_qubits (int): 量子线路中的量子比特数量。
trainable (bool): 层中的参数是否是可训练的。
"""
def __init__(self, num_qubits: int, trainable: bool = True) -> None:
super().__init__(num_qubits)
self._angle_attr = paddle.ParamAttr(
initializer=initializer.Uniform(0.0, 2*math.pi),
trainable=trainable
)
self.euler_angles = self.create_parameter(
shape=[3*num_qubits],
attr=self._angle_attr,
dtype="float64"
)
def forward(
self,
state: "paddle.Tensor[paddle.complex128]"
) -> "paddle.Tensor[paddle.complex128]":
r"""获取运行后的量子态
Args:
state (paddle.Tensor[paddle.complex128, shape=[n]]): 送入电路的量子态
Returns:
paddle.Tensor[paddle.complex128, shape=[n]]: 运行电路后的量子态
"""
cir0 = UAnsatz(self._n_qubit)
self._circuit = functional.euler_rotation_layer(cir0, self.euler_angles)
return self._circuit.run_state_vector(state)
def extra_repr(self):
r"""额外表示
"""
return "dtype={:s}".format(self.euler_angles.dtype.name)
# Cross resonance layer
class CrossResonanceLayer(QModel):
r"""在量子线路中按照给定的控制和目标比特添加一层 cross resonance 门。
Args:
num_qubits (int): 量子比特数目。
ctrl_qubit_index (list[int]): 控制比特的序号。
targ_qubit_index (list[int]): 目标比特的序号。
trainable (bool): 层中的参数是否可训练。
"""
def __init__(
self,
num_qubits: int,
ctrl_qubit_index: "list[int]" = None,
targ_qubit_index: "list[int]" = None,
trainable: bool = True
) -> None:
super().__init__(num_qubits)
if ctrl_qubit_index is None:
ctrl_qubit_index = list(range(num_qubits))
if targ_qubit_index is None:
targ_qubit_index = list(range(1, num_qubits)) + [0]
self._ctrl_qubit_index = ctrl_qubit_index
self._targ_qubit_index = targ_qubit_index
self._phase_attr = paddle.ParamAttr(
initializer=initializer.Uniform(0.0, 2*math.pi),
trainable=trainable
)
self.phase = self.create_parameter(
shape=[len(ctrl_qubit_index)],
attr=self._phase_attr,
dtype="float64"
)
def forward(
self,
state: "paddle.Tensor[paddle.complex128]"
) -> "paddle.Tensor[paddle.complex128]":
r"""获取运行后的量子态
Args:
state (paddle.Tensor[paddle.complex128, shape=[n]]): 送入电路的量子态
Returns:
paddle.Tensor[paddle.complex128, shape=[n]]: 运行电路后的量子态
"""
cir0 = UAnsatz(self._n_qubit)
self._circuit = functional.cr_layer(
cir0,
self.phase,
self._ctrl_qubit_index,
self._targ_qubit_index)
return self._circuit.run_state_vector(state)
def extra_repr(self):
r"""额外表示
"""
return "dtype={:s}".format(self.phase.dtype.name)
# !/usr/bin/env python3
# Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
qchem 开发所需的线性代数操作
"""
from typing import OrderedDict, Tuple
from collections import OrderedDict
import math
from copy import deepcopy
import paddle
DEFAULT_TOL = 1e-8
def get_givens_rotation_parameters(
a: paddle.Tensor,
b: paddle.Tensor
) -> Tuple[paddle.Tensor]:
r"""计算 Givens 旋转的 (c,s) 参数。
详细过程参见:https://www.netlib.org/lapack/lawnspdf/lawn148.pdf
Note:
:math:`r = \operatorname{sign}(a)\sqrt{a^2+b^2}, c = |a|/|r|, s = \operatorname{sign}(a)*b/|r|`
Args:
a (paddle.Tensor(dtype=float64)): 计算所用参数
b (paddle.Tensor(dtype=float64)): 计算所用参数
Returns:
tuple:
- c (paddle.Tensor(dtype=float64))
- s (paddle.Tensor(dtype=float64))
"""
assert a.dtype is paddle.float64 and b.dtype is paddle.float64,\
"dtype not match, require dtype of a, b be paddle.float64!"
if math.isclose(b.item(), 0.0, abs_tol=DEFAULT_TOL):
r = a
c = paddle.to_tensor(1.0, dtype=paddle.float64)
s = paddle.to_tensor(0.0, dtype=paddle.float64)
elif math.isclose(a.item(), 0.0, abs_tol=DEFAULT_TOL):
r = b.abs()
c = paddle.to_tensor(0.0, dtype=paddle.float64)
s = paddle.sign(b)
else:
abs_r = paddle.sqrt(a.abs()**2+b.abs()**2)
r = paddle.sign(a)*abs_r
c = a.abs()/abs_r
s = paddle.sign(a)*b/abs_r
return r, c, s
def parameter_to_givens_matrix1(c: paddle.Tensor, s: paddle.Tensor, j: int, n_size: int):
r"""该函数可利用 (c,s) 参数来构造 Givens 旋转矩阵以消去 A[i,j] 上的元素。
Args:
c (paddle.Tensor): :math:`|A[i,j-1]|/r`, 其中 :math:`r=\sqrt{A[i,j-1]^2+A[i,j]^2}`;
s (paddle.Tensor): :math:`\operatorname{sign}{(A[i,j]*A[i,j-1])*A[i,j]/r)}`;
j (int): 计算所用参数
n_size (int): Givens 旋转矩阵的维度
Returns:
Givens 旋转矩阵 (paddle.Tensor)
"""
G = paddle.eye(n_size, dtype=paddle.float64)
G[j - 1, j - 1] = c
G[j, j] = c
G[j - 1, j] = -s
G[j, j - 1] = s
return G
def givens_decomposition(A: paddle.Tensor) -> OrderedDict:
r"""对于一个给定的矩阵 A,该函数会返回一个 Givens 旋转操作的 list,用户可以使用其中的 Givens 旋转操作消除掉 A 的上三角的元素。
Note:
:math:`r = \operatorname{sign}(a)\sqrt{a^2+b^2}, c = |a|/|r|`
:math:`s = \operatorname{sign}(a)*b/|r| , \theta = arc\cos(c), phi = \operatorname{sign}(a*b)`
:math:`A^{\prime}[:,j-1] = c*A[:,j-1]+s*A[:,j]`
:math:`A^{\prime}[:,j] = -s*A[:,j-1]+c*A[:,j]`
Args:
A (paddle.Tensor(dtype=paddle.float64)): 矩阵
Returns:
OrderedDict, 包含 Givens 旋转操作以及其对应的参数。
"""
n = A.shape[0]
assert n == A.shape[1], "The input tensor should be a square matrix."
assert A.dtype is paddle.float64, "dtype of input tensor must be paddle.float64!"
# The givens rotations are not parallel !!!
A1 = deepcopy(A)
rotations = []
for i in range(n):
for j in range(n-1, i, -1):
_, c, s = get_givens_rotation_parameters(A1[i, j - 1], A1[i, j])
theta = paddle.acos(c)
phi = paddle.sign(A1[i, j - 1]*A1[i, j])
rotations.append((f"{i:>d},{j:>d}", (theta, phi)))
# update A matrix
A1_jprev = c*A1[:, j - 1] + s*A1[:, j]
A1_j = -s*A1[:, j-1] + c*A1[:, j]
A1[:, j-1] = A1_jprev
A1[:, j] = A1_j
return OrderedDict(rotations)
def parameters_to_givens_matrix2(
theta: paddle.Tensor,
phi: paddle.Tensor,
j: int,
n_size: int
) -> paddle.Tensor:
r"""该函数用来从 :math:`(\theta,\phi)` 参数中构建 Givens 旋转矩阵消去 :math:`A[i,j]`。
Args:
theta (paddle.Tensor): arccos(c);
phi (paddle.Tensor): :math:`\operatorname{sign}(A[i,j-1]*A[i,j])`;
j (int): 计算所用参数
n_size (int): Givens 旋转矩阵的维度。
Returns:
paddle.Tensor, Givens 旋转矩阵
"""
G = paddle.eye(int(n_size), dtype=paddle.float64)
G[j - 1, j - 1] = paddle.cos(theta)
G[j, j] = paddle.cos(theta)
G[j - 1, j] = -phi*paddle.sin(theta)
G[j, j - 1] = phi*paddle.sin(theta)
return G
# !/usr/bin/env python3
# Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
从分子结构等信息中提取量子化学需要的输入。
"""
from typing import Tuple, List
import numpy as np
from pyscf import gto, scf
from pyscf.lo import lowdin
# Transform one and two body integral into L\"owdin basis
def lowdin_transform(
ovlp: np.array,
onebody: np.array,
twobody: np.array
) -> Tuple[np.array]:
r"""该函数会将 pyscf 中得到的高斯积分利用 L\"owdin 正交化方法进行变换。
Note:
L\"owdin 正交化:
:math:`S_{ij}=\langle\phi_i^{\text{G}}|\phi_j^{\text{G}}\rangle`,
:math:`X = S^{-1/2}`
Operators 的变换方式:
:math:`A^{\prime}_{ij}=\sum_{pq}A_{pq}X_{ip}X_{qj}`
:math:`B^{\prime}_{iklj}=\sum_{pqrs}B_{prsq}X_{ip}X_{kr}X_{sl}X_{qj}`
分子轨道的变换方式:
:math:`C^{\prime}_{ij}=\sum_{p}C_{pj}X^{-1}_{ip}`
Args:
ovlp (np.array): 交叠积分,`mol.intor("int1e_ovlp")`。
onebody (np.array): 单体积分,`mol.intor("int1e_kin")+mol.intor("int1e_nuc")`。
twobody (np.array): 两体积分,`mol.intor("int2e")`。
Returns:
Tuple[np.array]:
- 变换之后的单体积分。
- 变换之后的两体积分。
"""
inv_half_ovlp = lowdin(ovlp)
t_onebody = inv_half_ovlp @ onebody @ inv_half_ovlp
t_twobody = np.einsum(
"pqrs,ip,qj,kr,sl->ijkl",
twobody, inv_half_ovlp, inv_half_ovlp, inv_half_ovlp, inv_half_ovlp
)
return t_onebody, t_twobody
# Molecular information
def get_molecular_information(
geometry: List[Tuple[str, List]],
basis: str = "sto-3g",
charge: int = 0,
debug: bool = False
) -> Tuple:
r"""该函数会返回量子化学(目前是 "hartree fock" 方法)计算所需要的分子信息,包括有计算需要的量子比特的数量,分子中的电子数,分子积分和 pyscf 平均场结果 (optional)。
Args:
geometry (List[Tuple[str,List]]): 分子中各原子笛卡尔坐标;
basis (str): 基函数名称,例如:"sto-3g";
charge (int): 分子的电荷;
debug (bool): 是否使用 debug 模式。debug 模式会返回 pyscf 的平均场计算结果。
Returns:
Tuple:
- 量子比特数目;
- 分子中的电子数;
- 原子核之间的排斥能、单体积分、双体积分;
- pyscf 的平均场计算结果 (可选,只有 debug=True 才会返回)。
"""
mol = gto.M(atom=geometry, basis=basis, charge=charge, unit="angstrom")
mol.build()
if debug:
mf_mol = scf.RHF(mol).run()
int_ovlp = mol.intor("int1e_ovlp")
nuc_energy = mol.energy_nuc()
onebody = mol.intor("int1e_kin") + mol.intor("int1e_nuc")
twobody = mol.intor("int2e")
orth_onebody, orth_twobody = lowdin_transform(int_ovlp, onebody, twobody)
if debug:
return 2*mol.nao, mol.nelectron, (nuc_energy, orth_onebody, 0.5*orth_twobody), mf_mol
else:
return 2*mol.nao, mol.nelectron, (nuc_energy, orth_onebody, 0.5*orth_twobody)
# !/usr/bin/env python3
# Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved. # Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
...@@ -13,7 +14,7 @@ ...@@ -13,7 +14,7 @@
# limitations under the License. # limitations under the License.
""" """
Quantum chemistry module 量子化学模块
""" """
import os import os
...@@ -73,14 +74,14 @@ def _hamiltonian_transformation(spin_h, tol=1e-8): ...@@ -73,14 +74,14 @@ def _hamiltonian_transformation(spin_h, tol=1e-8):
def _geo_str(geometry): def _geo_str(geometry):
r"""创建分子几何信息的字符串 r"""创建分子几何信息的字符串
Args: Args:
geometry (list): 包含了分子的几何信息,以 H2 分子为例 geometry (list): 包含了分子的几何信息,以 H2 分子为例
[['H', [-1.68666, 1.79811, 0.0]], ['H', [-1.12017, 1.37343, 0.0]]] [['H', [-1.68666, 1.79811, 0.0]], ['H', [-1.12017, 1.37343, 0.0]]]
Returns: Returns:
str: 分子几何信息的字符串 str: 分子几何信息的字符串
""" """
geo_str = '' geo_str = ''
for item in geometry: for item in geometry:
...@@ -98,26 +99,26 @@ def _geo_str(geometry): ...@@ -98,26 +99,26 @@ def _geo_str(geometry):
def _run_psi4( def _run_psi4(
molecule, molecule,
charge, charge,
multiplicity, multiplicity,
method, method,
basis, basis,
if_print, if_print,
if_save if_save
): ):
r"""计算分子的必要信息,包括单体积分 (one-body integrations) 和双体积分 (two-body integrations), r"""计算分子的必要信息,包括单体积分 (one-body integrations) 和双体积分 (two-body integrations),
以及用 scf 和 fci 的方法计算基态的能量。 以及用 scf 和 fci 的方法计算基态的能量。
Args: Args:
molecule (MolecularData object): 包含分子所有信息的类 (class) molecule (MolecularData object): 包含分子所有信息的类 (class)
charge (int): 分子的电荷 charge (int): 分子的电荷
multiplicity (int): 分子的多重度 multiplicity (int): 分子的多重度
method (str): 用于计算基态能量的方法,包括 'scf'和 'fci' method (str): 用于计算基态能量的方法,包括 'scf'和 'fci'
basis (str): 常用的基组是 'sto-3g', '6-31g'等。更多的基组选择可以参考网站 basis (str): 常用的基组是 'sto-3g', '6-31g'等。更多的基组选择可以参考网站
https://psicode.org/psi4manual/master/basissets_byelement.html#apdx-basiselement。 https://psicode.org/psi4manual/master/basissets_byelement.html#apdx-basiselement
if_print (Boolean): 是否需要打印出选定方法 (method) 计算出的分子基态能量 if_print (Boolean): 是否需要打印出选定方法 (method) 计算出的分子基态能量
if_save (Boolean): 是否需要将分子信息存储成 .hdf5 文件 if_save (Boolean): 是否需要将分子信息存储成 .hdf5 文件
""" """
psi4.set_memory('500 MB') psi4.set_memory('500 MB')
psi4.set_options({'soscf': 'false', psi4.set_options({'soscf': 'false',
...@@ -182,7 +183,7 @@ def _run_psi4( ...@@ -182,7 +183,7 @@ def _run_psi4(
def geometry(structure=None, file=None): def geometry(structure=None, file=None):
r"""读取分子的几何信息 r"""读取分子的几何信息
Args: Args:
structure (string, optional): 分子几何信息的字符串形式,以 H2 分子为例 structure (string, optional): 分子几何信息的字符串形式,以 H2 分子为例
...@@ -193,9 +194,9 @@ def geometry(structure=None, file=None): ...@@ -193,9 +194,9 @@ def geometry(structure=None, file=None):
str: 分子的几何信息 str: 分子的几何信息
Raises: Raises:
AssertionError: 两个输入参数不可以同时为 ``None`` AssertionError: 两个输入参数不可以同时为 ``None``
""" """
if ((structure is None) and (file is None)): if structure is None and file is None:
raise AssertionError('Input must be structure or .xyz file') raise AssertionError('Input must be structure or .xyz file')
elif file is None: elif file is None:
shape = np.array(structure).shape shape = np.array(structure).shape
...@@ -221,15 +222,15 @@ def geometry(structure=None, file=None): ...@@ -221,15 +222,15 @@ def geometry(structure=None, file=None):
def get_molecular_data( def get_molecular_data(
geometry, geometry,
charge=0, charge=0,
multiplicity=1, multiplicity=1,
basis='sto-3g', basis='sto-3g',
method='scf', method='scf',
if_save=True, if_save=True,
if_print=True, if_print=True,
name="", name="",
file_path="." file_path="."
): ):
r"""计算分子的必要信息,包括单体积分(one-body integrations)和双体积分(two-body integrations), r"""计算分子的必要信息,包括单体积分(one-body integrations)和双体积分(two-body integrations),
以及用选定的方法计算基态的能量。 以及用选定的方法计算基态的能量。
...@@ -270,28 +271,34 @@ def get_molecular_data( ...@@ -270,28 +271,34 @@ def get_molecular_data(
else: else:
filename = name + '.hdf5' filename = name + '.hdf5'
molecule = MolecularData(geometry, molecule = MolecularData(
basis=basis, geometry,
multiplicity=multiplicity, basis=basis,
charge=charge, multiplicity=multiplicity,
filename=filename) charge=charge,
filename=filename
)
_run_psi4(molecule, _run_psi4(
charge, molecule,
multiplicity, charge,
method, multiplicity,
basis, method,
if_print, basis,
if_save) if_print,
if_save
)
return molecule return molecule
def active_space(electrons, def active_space(
orbitals, electrons,
multiplicity=1, orbitals,
active_electrons=None, multiplicity=1,
active_orbitals=None): active_electrons=None,
active_orbitals=None
):
r"""对于给定的活跃电子和活跃轨道计算相应的活跃空间(active space)。 r"""对于给定的活跃电子和活跃轨道计算相应的活跃空间(active space)。
Args: Args:
...@@ -340,11 +347,13 @@ def active_space(electrons, ...@@ -340,11 +347,13 @@ def active_space(electrons,
return core_orbitals, active_orbitals return core_orbitals, active_orbitals
def fermionic_hamiltonian(molecule, def fermionic_hamiltonian(
filename=None, molecule,
multiplicity=1, filename=None,
active_electrons=None, multiplicity=1,
active_orbitals=None): active_electrons=None,
active_orbitals=None
):
r"""计算给定分子的费米哈密顿量。 r"""计算给定分子的费米哈密顿量。
Args: Args:
...@@ -375,12 +384,14 @@ def fermionic_hamiltonian(molecule, ...@@ -375,12 +384,14 @@ def fermionic_hamiltonian(molecule,
return fermionic_hamiltonian return fermionic_hamiltonian
def spin_hamiltonian(molecule, def spin_hamiltonian(
filename=None, molecule,
multiplicity=1, filename=None,
mapping_method='jordan_wigner', multiplicity=1,
active_electrons=None, mapping_method='jordan_wigner',
active_orbitals=None): active_electrons=None,
active_orbitals=None
):
r"""生成 Paddle Quantum 格式的哈密顿量 r"""生成 Paddle Quantum 格式的哈密顿量
Args: Args:
......
# !/usr/bin/env python3
# Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
用于构建量子电路层的基类
该模块依赖 paddlepaddle。
"""
from paddle import nn
class QModel(nn.Layer):
r"""量子化学用量子线路的基类,任何自定义量子线路都需要继承自这个类。
"""
def __init__(self, num_qubit: int):
r"""构造函数
Args:
num_qubit (int): 量子比特数目
"""
super().__init__(name_scope="QModel")
self._n_qubit = num_qubit
self._circuit = None
@property
def n_qubit(self):
r"""量子比特数目
"""
return self._n_qubit
@property
def circuit(self):
r"""量子电路
"""
if self._circuit is None:
print("Circuit is not built, please run `forward` to build the circuit first.")
return None
else:
return self._circuit
# !/usr/bin/env python3
# Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
利用不同的 ansatz 运行量子化学计算。
"""
from typing import List, Tuple, Callable
import numpy as np
import paddle
from paddle.optimizer import Optimizer, Adam
from . import qchem as pq_chem
import paddle_quantum.state as pq_state
from paddle_quantum.intrinsic import vec_expecval
from .ansatz.rhf import RestrictHartreeFockModel
from .qmodel import QModel
from .ansatz import HardwareEfficientModel
def _minimize(
model: QModel,
loss_fn: Callable[[QModel], Tuple[float, QModel]],
optimizer: Optimizer,
max_iters: int,
a_tol: float
) -> Tuple[float, QModel]:
loss_prev = -np.inf
for i in range(max_iters):
with paddle.no_grad():
loss = loss_fn(model)
print(f"Iteration {i+1:>d}, {model.__class__.__name__} energy {loss.item():>.5f}.")
if np.abs(loss.item() - loss_prev) < a_tol:
print(f"Converge after {(i+1):>d} number of iterations.")
break
else:
loss_prev = loss.item()
optimizer.clear_grad()
loss = loss_fn(model)
loss.backward()
optimizer.step()
with paddle.no_grad():
loss = loss_fn(model)
return loss.item(), model
def run_chem(
geometry: List[Tuple[str, List[float]]],
ansatz: str,
basis_set: str = "sto-3g",
charge: int = 0,
max_iters: int = 100,
a_tol: float = 1e-6,
optimizer_option: dict = {},
ansatz_option: dict = {}
) -> Tuple[float, QModel]:
r"""根据输入的分子信息进行量子化学计算。
Args:
geometry (List[Tuple[str, List[float]]]): 分子的几何结构,例如:[("H", [0.0, 0.0, 0.0]), ("H", [0.0, 0.0, 0.74])]。定义结构时使用的长度单位是 Angstrom。
ansatz (str): 表示多体波函数的量子线路,目前我们支持 "hardware efficient" 和 "hartree fock"。
basis_set (str): 用来展开原子轨道的量子化学的基函数,例如:"sto-3g"。注意,复杂的基函数会极大占用计算资源。
charge (int): 分子的电荷量。
max_iters (int): 优化过程的最大迭代次数。
a_tol (float): 优化收敛的判断依据,当 :math:`|e_{i+1} - e_i| < a_{tol}` 时,优化结束。
optimizer_options (dict): 优化器的可选参数,例如:学习率 (learning_rate)、权重递减 (weight_decay)。
ansatz_option (dict): 定义 ansatz 量子线路的可选参数。目前,对于 "hardware efficient" 方法,可选参数为 "cir_depth"(线路深度)。"hartree fock" 方法没有可选参数。
Returns:
tuple:
- 基态能量
- 优化后的 ansatz 量子线路
"""
if ansatz == "hardware efficient":
return run_hardware(
geometry, basis_set, charge,
max_iters, a_tol, optimizer_option, **ansatz_option
)
if ansatz == "hartree fock":
return run_rhf(
geometry, basis_set, charge,
max_iters, a_tol, optimizer_option, **ansatz_option
)
else:
raise NotImplementedError(
"""
Currently, we only support "hardware efficient" or "hartree fock" for `ansatz` parameter, we will add more in the future. You can open an issue here
https://github.com/PaddlePaddle/Quantum/issues to report the ansatz you're interested in.
""")
def run_hardware(
geometry: List[Tuple[str, List[float]]],
basis_set: str,
charge: int,
max_iters: int,
a_tol: float,
optimizer_option: dict = {},
cir_depth: int = 3
) -> Tuple[float, QModel]:
r"""hardware efficient 方法的 run 函数。
"""
mol_data = pq_chem.get_molecular_data(geometry, basis=basis_set, charge=charge, if_print=False)
mol_qubitH = pq_chem.spin_hamiltonian(mol_data)
n_qubits = mol_qubitH.n_qubits
ansatz = HardwareEfficientModel(n_qubits, cir_depth)
optimizer = Adam(parameters=ansatz.parameters(), **optimizer_option)
s0 = paddle.to_tensor(pq_state.vec(0, n_qubits))
s0 = paddle.reshape(s0, [2**n_qubits])
def loss_fn(model: QModel) -> paddle.Tensor:
s = model(s0)
return paddle.real(vec_expecval(mol_qubitH.pauli_str, s))
mol_gs_en, updated_ansatz = _minimize(ansatz, loss_fn, optimizer, max_iters, a_tol)
return mol_gs_en, updated_ansatz
def run_rhf(
geometry: List[Tuple[str, List[float]]],
basis_set: str,
charge: int,
max_iters: int,
a_tol: float,
optimizer_option: dict = {}
) -> Tuple[float, QModel]:
r"""hartree fock 方法的 run 函数。
"""
try:
import pyscf
except ModuleNotFoundError as e:
raise ModuleNotFoundError(
"""
Hartree Fock method needs `pyscf`,
please run `pip install -U pyscf` to first install pyscf.
""")
from .molecule import get_molecular_information
n_qubits, n_electrons, integrals = get_molecular_information(geometry, basis_set, charge)
nuc_energy, onebody, twobody = [paddle.to_tensor(t) for t in integrals]
ansatz = RestrictHartreeFockModel(n_qubits, n_electrons, onebody)
optimizer = Adam(parameters=ansatz.parameters(), **optimizer_option)
# run model to build the circuit
bstr = "1"*n_electrons+"0"*(n_qubits-n_electrons)
_s0 = paddle.to_tensor(pq_state.vec(int(bstr, 2), n_qubits))
_s0 = paddle.reshape(_s0, [2**n_qubits])
ansatz(_s0)
def loss_fn(model: QModel) -> paddle.Tensor:
U_hf = model.single_particle_U()
rdm1 = U_hf @ U_hf.conj().t()
return nuc_energy + 2*paddle.einsum("pq,qp->", onebody, rdm1)\
+ 4*paddle.einsum("pqrs,qp,sr->", twobody, rdm1, rdm1)\
- 2*paddle.einsum("pqrs,sp,qr->", twobody, rdm1, rdm1)
mol_gs_en, updated_ansatz = _minimize(ansatz, loss_fn, optimizer, max_iters, a_tol)
return mol_gs_en, updated_ansatz
...@@ -19,6 +19,7 @@ shadow sample module ...@@ -19,6 +19,7 @@ shadow sample module
import numpy as np import numpy as np
import paddle import paddle
import re import re
import math
from paddle_quantum import circuit from paddle_quantum import circuit
from paddle_quantum.utils import Hamiltonian from paddle_quantum.utils import Hamiltonian
...@@ -27,6 +28,120 @@ __all__ = [ ...@@ -27,6 +28,120 @@ __all__ = [
] ]
def random_pauli_sample(num_qubits, beta=None):
r"""根据概率分布 beta, 随机选取 pauli 测量基
Args:
num_qubits (int): 量子比特数目
beta (list, optional): 量子位上不同 pauli 测量基的概率分布
Returns:
str: 返回随机选择的 pauli 测量基
Note:
这是内部函数,你并不需要直接调用到该函数。
"""
# assume beta obeys a uniform distribution if it is not given
if beta is None:
beta = list()
for _ in range(0, num_qubits):
beta.append([1 / 3] * 3)
pauli_sample = str()
for qubit_idx in range(num_qubits):
sample = np.random.choice(['x', 'y', 'z'], 1, p=beta[qubit_idx])
pauli_sample += sample[0]
return pauli_sample
def measure_by_pauli_str(pauli_str, phi, num_qubits, mode, method):
r"""搭建 pauli 测量电路,返回测量结果
Args:
pauli_str (str): 输入的是随机选取的num_qubits pauli 测量基
phi (numpy.ndarray): 输入量子态,支持态矢量和密度矩阵形式
num_qubits (int): 量子比特数量
mode (str): 输入量子态的表示方式,``"state_vector"`` 表示态矢量形式, ``"density_matrix"`` 表示密度矩阵形式
method (str): 进行测量的方法,有 "CS"、"LBCS"、"APS"
Returns:
str: 返回测量结果
Note:
这是内部函数,你并不需要直接调用到该函数。
"""
if method == "clifford":
# Add the clifford function
pass
else:
# Other method are transformed as follows
# Convert to tensor form
input_state = paddle.to_tensor(phi)
cir = circuit.UAnsatz(num_qubits)
for qubit in range(num_qubits):
if pauli_str[qubit] == 'x':
cir.h(qubit)
elif pauli_str[qubit] == 'y':
cir.h(qubit)
cir.s(qubit)
cir.h(qubit)
if mode == 'state_vector':
cir.run_state_vector(input_state)
else:
cir.run_density_matrix(input_state)
result = cir.measure(shots=1)
bit_string, = result
return bit_string
def paulistr_to_matrix(paulistr):
r"""识别随机选取的 pauli 并转换成作用于 Z 测量的酉变换的矩阵形式
Args:
paulistr (str): 输入的是某一量子位上随机选取的 Pauli 测量基
Returns:
numpy.ndarray: 返回酉变换的矩阵形式
Note:
这是内部函数,你并不需要直接调用到该函数。
"""
# Define the matrix form of H, S gates
a = math.pow(2, 0.5)
H_matrix = np.array([[1 / a, 1 / a], [1 / a, -1 / a]])
S_matrix = np.array([[1, 0], [0, 1j]])
I_matrix = np.array([[1, 0], [0, 1]])
if paulistr == 'x':
paulistr_matrix = H_matrix
elif paulistr == 'y':
paulistr_matrix = np.dot(np.dot(H_matrix, S_matrix), H_matrix)
elif paulistr == 'z':
paulistr_matrix = I_matrix
return paulistr_matrix
def measure_result_to_matrix(measure_str):
r"""将单个量子位上测量的结果转换为密度矩阵形式
Args:
measure_str (str): 输入的是某一量子位上的测量结果
Returns:
numpy.ndarray: 返回测量结果的密度矩阵形式
Note:
这是内部函数,你并不需要直接调用到该函数。
"""
ket_0 = np.array([[1, 0]]).T
ket_1 = np.array([[0, 1]]).T
if measure_str == '0':
b_matrix = np.kron(ket_0, ket_0.conj().T)
elif measure_str == '1':
b_matrix = np.kron(ket_1, ket_1.conj().T)
return b_matrix
def shadow_sample(state, num_qubits, sample_shots, mode, hamiltonian=None, method='CS'): def shadow_sample(state, num_qubits, sample_shots, mode, hamiltonian=None, method='CS'):
r"""对给定的量子态进行随机的泡利测量并返回测量结果。 r"""对给定的量子态进行随机的泡利测量并返回测量结果。
...@@ -108,68 +223,6 @@ def shadow_sample(state, num_qubits, sample_shots, mode, hamiltonian=None, metho ...@@ -108,68 +223,6 @@ def shadow_sample(state, num_qubits, sample_shots, mode, hamiltonian=None, metho
pauli2index = {'x': 0, 'y': 1, 'z': 2} pauli2index = {'x': 0, 'y': 1, 'z': 2}
def random_pauli_sample(num_qubits, beta=None):
r"""根据概率分布 beta, 随机选取 pauli 测量基
Args:
num_qubits (int): 量子比特数目
beta (list, optional): 量子位上不同 pauli 测量基的概率分布
Returns:
str: 返回随机选择的 pauli 测量基
Note:
这是内部函数,你并不需要直接调用到该函数。
"""
# assume beta obeys a uniform distribution if it is not given
if beta is None:
beta = list()
for _ in range(0, num_qubits):
beta.append([1 / 3] * 3)
pauli_sample = str()
for qubit_idx in range(num_qubits):
sample = np.random.choice(['x', 'y', 'z'], 1, p=beta[qubit_idx])
pauli_sample += sample[0]
return pauli_sample
def measure_by_pauli_str(pauli_str, phi, num_qubits, method):
r"""搭建 pauli 测量电路,返回测量结果
Args:
pauli_str (str): 输入的是随机选取的num_qubits pauli 测量基
phi (numpy.ndarray): 输入量子态,支持态矢量和密度矩阵形式
num_qubits (int): 量子比特数量
method (str): 进行测量的方法,有 "CS"、"LBCS"、"APS"
Returns:
str: 返回测量结果
Note:
这是内部函数,你并不需要直接调用到该函数。
"""
if method == "clifford":
# Add the clifford function
pass
else:
# Other method are transformed as follows
# Convert to tensor form
input_state = paddle.to_tensor(phi)
cir = circuit.UAnsatz(num_qubits)
for qubit in range(num_qubits):
if pauli_str[qubit] == 'x':
cir.h(qubit)
elif pauli_str[qubit] == 'y':
cir.h(qubit)
cir.s(qubit)
cir.h(qubit)
if mode == 'state_vector':
cir.run_state_vector(input_state)
else:
cir.run_density_matrix(input_state)
result = cir.measure(shots=1)
bit_string, = result
return bit_string
# Define the function used to update the beta of the LBCS algorithm # Define the function used to update the beta of the LBCS algorithm
def calculate_diagonal_product(pauli_str, beta): def calculate_diagonal_product(pauli_str, beta):
r"""迭代 LBCS beta 公式中的一部分 r"""迭代 LBCS beta 公式中的一部分
...@@ -424,7 +477,7 @@ def shadow_sample(state, num_qubits, sample_shots, mode, hamiltonian=None, metho ...@@ -424,7 +477,7 @@ def shadow_sample(state, num_qubits, sample_shots, mode, hamiltonian=None, metho
if method == "CS": if method == "CS":
for _ in range(sample_shots): for _ in range(sample_shots):
random_pauli_str = random_pauli_sample(num_qubits, beta=None) random_pauli_str = random_pauli_sample(num_qubits, beta=None)
measurement_result = measure_by_pauli_str(random_pauli_str, state, num_qubits, method) measurement_result = measure_by_pauli_str(random_pauli_str, state, num_qubits, mode, method)
sample_result.append((random_pauli_str, measurement_result)) sample_result.append((random_pauli_str, measurement_result))
return sample_result return sample_result
elif method == "LBCS": elif method == "LBCS":
...@@ -441,12 +494,91 @@ def shadow_sample(state, num_qubits, sample_shots, mode, hamiltonian=None, metho ...@@ -441,12 +494,91 @@ def shadow_sample(state, num_qubits, sample_shots, mode, hamiltonian=None, metho
sample_result = list() sample_result = list()
for _ in range(sample_shots): for _ in range(sample_shots):
random_pauli_str = random_pauli_sample(num_qubits, beta) random_pauli_str = random_pauli_sample(num_qubits, beta)
measurement_result = measure_by_pauli_str(random_pauli_str, state, num_qubits, method) measurement_result = measure_by_pauli_str(random_pauli_str, state, num_qubits, mode, method)
sample_result.append((random_pauli_str, measurement_result)) sample_result.append((random_pauli_str, measurement_result))
return sample_result, beta return sample_result, beta
elif method == "APS": elif method == "APS":
for _ in range(sample_shots): for _ in range(sample_shots):
random_pauli_str = random_pauli_sample_in_aps(hamiltonian) random_pauli_str = random_pauli_sample_in_aps(hamiltonian)
measurement_result = measure_by_pauli_str(random_pauli_str, state, num_qubits, method) measurement_result = measure_by_pauli_str(random_pauli_str, state, num_qubits, mode, method)
sample_result.append((random_pauli_str, measurement_result)) sample_result.append((random_pauli_str, measurement_result))
return sample_result return sample_result
def classical_shadow(state, num_qubits, sample_shots, mode, method=None):
r"""获得量子态 state 的经典影子
Args:
state (numpy.ndarray): 输入量子态,支持态矢量和密度矩阵形式
num_qubits (int): 量子比特数量
sample_shots (int): 随机采样的次数
mode (str): 输入量子态的表示方式,``"state_vector"`` 表示态矢量形式, ``"density_matrix"`` 表示密度矩阵形式
method (str, optional): 可选方法 restructure (R),获得量子态的密度矩阵形式;或默认为None (即 not restructure, NR),获得量子态的密度矩阵形式
Returns:
tuple: 包含如下两个元素
- state_hat (list): 返回量子态 state 的经典影子 (method = 'NR')
- reconstructed_state (numpy.ndarray): 返回估计的量子态 state 的密度矩阵 (method = 'R')
代码示例:
.. code-block:: python
from paddle_quantum.shadow import classical_shadow
from paddle_quantum.state import vec_random
n_qubit = 2
sample_shots = 2
state = vec_random(n_qubit)
state_shadow = classical_shadow(state, n_qubit, sample_shots, mode='state_vector', method='NR')
state_density_matrix = classical_shadow(state, n_qubit, sample_shots, mode='state_vector', method='R')
print('classical shadow of quantum state = ', state_shadow)
print('density matrix of quantum state = ', state_density_matrix)
::
classical shadow of quantum state = [array([[ 0.25+0.j , 0. +0.75j, -0.75+0.j , -0. -2.25j],
[ 0. -0.75j, 0.25+0.j , 0. +2.25j, -0.75+0.j ],
[-0.75+0.j , -0. -2.25j, 0.25+0.j , 0. +0.75j],
[ 0. +2.25j, -0.75+0.j , 0. -0.75j, 0.25+0.j ]]),
array([[0.25+0.j , 0. -0.75j, 0.75+0.j , 0. -2.25j],
[0. +0.75j, 0.25+0.j , 0. +2.25j, 0.75+0.j ],
[0.75+0.j , 0. -2.25j, 0.25+0.j , 0. -0.75j],
[0. +2.25j, 0.75+0.j , 0. +0.75j, 0.25+0.j ]])]
density matrix of quantum state = [[ 0.625+0.j 0.375+0.j -1.5 +0.375j 0. +1.125j]
[ 0.375+0.j -0.125+0.j 0. +1.125j 0.75 +0.375j]
[-1.5 -0.375j 0. -1.125j 0.625+0.j 0.375+0.j ]
[ 0. -1.125j 0.75 -0.375j 0.375+0.j -0.125+0.j ]]
"""
# Used to store the classic shadow for each sample
state_hat = []
I_matrix = np.array([[1, 0], [0, 1]])
for _ in range(sample_shots):
# Randomly selected Pauli
random_pauli_str = random_pauli_sample(num_qubits, beta=None)
# Measure according to the selected Pauli
measurement_result = measure_by_pauli_str(random_pauli_str, state, num_qubits, mode, None)
# Generate a 1×1 matrix, convenient tensor product
hat_state = np.eye(1)
for i in range(num_qubits):
single_pauli_matrix = paulistr_to_matrix(random_pauli_str[i])
single_b_matrix = measure_result_to_matrix(measurement_result[i])
# The classical shadow on a single qubit is obtained according to the derived M inverse
single_qubit_state_left = np.dot(np.dot(single_pauli_matrix.conj().T, single_b_matrix), single_pauli_matrix)
single_qubit_state = 3 * single_qubit_state_left - I_matrix
# The classical shadow of quantum state is obtained
hat_state = np.kron(hat_state, single_qubit_state)
# Store classical shadows
state_hat.append(hat_state)
if method == 'R':
# Returns the density matrix of the quantum state
reconstructed_state = sum(state_hat)/len(state_hat)
return reconstructed_state
else:
# Returns the classical shadow of the quantum state
return state_hat
...@@ -69,38 +69,9 @@ def init_state_gen(n, i=0): ...@@ -69,38 +69,9 @@ def init_state_gen(n, i=0):
""" """
assert 0 <= i < 2 ** n, 'Invalid index' assert 0 <= i < 2 ** n, 'Invalid index'
if n == 1: state = np.zeros([2 ** n], dtype=np.complex128)
state1 = paddle.ones([1], 'float64') state[i] = 1
state0 = paddle.zeros([2 ** n - 1], 'float64') state = paddle.to_tensor(state)
if i == 0:
state = paddle.concat([state1, state0])
else:
state = paddle.concat([state0, state1])
else:
if i == 0:
state1 = paddle.ones([1], 'float64')
state0 = paddle.zeros([2 ** n - 1], 'float64')
state = paddle.concat([state1, state0])
elif i == 2 ** n - 1:
state1 = paddle.ones([1], 'float64')
state0 = paddle.zeros([2 ** n - 1], 'float64')
state = paddle.concat([state0, state1])
else:
state1 = paddle.ones([1], 'float64')
state0 = paddle.zeros([i], 'float64')
state00 = paddle.zeros([2 ** n - i - 1], 'float64')
state = paddle.concat([state0, state1, state00])
del state1, state0
try:
del state00
except NameError:
pass
gc.collect() # free the intermediate big data immediately
state = paddle.cast(state, 'complex128')
gc.collect() # free the intermediate big data immediately
return state return state
......
...@@ -28,15 +28,15 @@ PI = paddle.to_tensor(np.pi, dtype='float64') ...@@ -28,15 +28,15 @@ PI = paddle.to_tensor(np.pi, dtype='float64')
def construct_trotter_circuit( def construct_trotter_circuit(
circuit: UAnsatz, circuit: UAnsatz,
hamiltonian: Hamiltonian, hamiltonian: Hamiltonian,
tau: float, tau: float,
steps: int, steps: int,
method: str = 'suzuki', method: str = 'suzuki',
order: int = 1, order: int = 1,
grouping: str = None, grouping: str = None,
coefficient: np.ndarray or paddle.Tensor = None, coefficient: np.ndarray or paddle.Tensor = None,
permutation: np.ndarray = None permutation: np.ndarray = None
): ):
r"""向 circuit 的后面添加 trotter 时间演化电路,即给定一个系统的哈密顿量 H,该电路可以模拟系统的时间演化 :math:`U_{cir}~ e^{-iHt}` 。 r"""向 circuit 的后面添加 trotter 时间演化电路,即给定一个系统的哈密顿量 H,该电路可以模拟系统的时间演化 :math:`U_{cir}~ e^{-iHt}` 。
...@@ -249,7 +249,7 @@ def _add_custom_block(circuit, tau, grouped_hamiltonian, custom_coefficients, pe ...@@ -249,7 +249,7 @@ def _add_custom_block(circuit, tau, grouped_hamiltonian, custom_coefficients, pe
add_n_pauli_gate(circuit, 2 * tau * coeff, pauli_word, site) add_n_pauli_gate(circuit, 2 * tau * coeff, pauli_word, site)
def __add_first_order_trotter_block(circuit, tau, grouped_hamiltonian, reverse=False): def __add_first_order_trotter_block(circuit, tau, grouped_hamiltonian, reverse=False, optimization=False):
r""" 添加一阶 trotter-suzuki 分解的时间演化块 r""" 添加一阶 trotter-suzuki 分解的时间演化块
Notes: Notes:
...@@ -258,54 +258,57 @@ def __add_first_order_trotter_block(circuit, tau, grouped_hamiltonian, reverse=F ...@@ -258,54 +258,57 @@ def __add_first_order_trotter_block(circuit, tau, grouped_hamiltonian, reverse=F
if not reverse: if not reverse:
for hamiltonian in grouped_hamiltonian: for hamiltonian in grouped_hamiltonian:
assert isinstance(hamiltonian, Hamiltonian) assert isinstance(hamiltonian, Hamiltonian)
if optimization:
#将原哈密顿量中相同site的XX,YY,ZZ组合到一起 # Combine XX, YY, ZZ of the same site in the original Hamiltonian quantity
grouped_hamiltonian = [] grouped_hamiltonian = []
coeffs, pauli_words, sites = hamiltonian.decompose_with_sites() coeffs, pauli_words, sites = hamiltonian.decompose_with_sites()
grouped_terms_indices = [] grouped_terms_indices = []
left_over_terms_indices = [] left_over_terms_indices = []
d = defaultdict(list) d = defaultdict(list)
#合并相同site的XX,YY,ZZ # Merge XX,YY,ZZ of the same site
for term_index in range(len(coeffs)): for term_index in range(len(coeffs)):
site = sites[term_index] site = sites[term_index]
pauli_word = pauli_words[term_index] pauli_word = pauli_words[term_index]
for pauli in ['XX', 'YY', 'ZZ']: for pauli in ['XX', 'YY', 'ZZ']:
assert isinstance(pauli_word, str), "Each pauli word should be a string type" assert isinstance(pauli_word, str), "Each pauli word should be a string type"
if (pauli_word==pauli or pauli_word==pauli.lower()): if (pauli_word == pauli or pauli_word == pauli.lower()):
key = tuple(sorted(site)) key = tuple(sorted(site))
d[key].append((pauli,term_index)) d[key].append((pauli, term_index))
if len(d[key])==3: if len(d[key]) == 3:
terms_indices_to_be_grouped = [x[1] for x in d[key]] terms_indices_to_be_grouped = [x[1] for x in d[key]]
grouped_terms_indices.extend(terms_indices_to_be_grouped) grouped_terms_indices.extend(terms_indices_to_be_grouped)
grouped_hamiltonian.append(hamiltonian[terms_indices_to_be_grouped]) grouped_hamiltonian.append(hamiltonian[terms_indices_to_be_grouped])
#其他的剩余项 # Other remaining sites
for term_index in range(len(coeffs)): for term_index in range(len(coeffs)):
if term_index not in grouped_terms_indices: if term_index not in grouped_terms_indices:
left_over_terms_indices.append(term_index) left_over_terms_indices.append(term_index)
if len(left_over_terms_indices): if len(left_over_terms_indices):
for term_index in left_over_terms_indices: for term_index in left_over_terms_indices:
grouped_hamiltonian.append(hamiltonian[term_index]) grouped_hamiltonian.append(hamiltonian[term_index])
#得到新的哈密顿量 # Get the new Hamiltonian
res = grouped_hamiltonian[0] res = grouped_hamiltonian[0]
for i in range(1,len(grouped_hamiltonian)): for i in range(1, len(grouped_hamiltonian)):
res+=grouped_hamiltonian[i] res += grouped_hamiltonian[i]
hamiltonian = res hamiltonian = res
# decompose the Hamiltonian into 3 lists # decompose the Hamiltonian into 3 lists
coeffs, pauli_words, sites = hamiltonian.decompose_with_sites() coeffs, pauli_words, sites = hamiltonian.decompose_with_sites()
# apply rotational gate of each term # apply rotational gate of each term
# for term_index in range(len(coeffs)):
# # get the sorted pauli_word and site (an array of qubit indices) according to their qubit indices
# pauli_word, site = __sort_pauli_word(pauli_words[term_index], sites[term_index])
# add_n_pauli_gate(circuit, 2 * tau * coeffs[term_index], pauli_word, site)
term_index = 0 term_index = 0
while term_index <len(coeffs): while term_index < len(coeffs):
if term_index+3<=len(coeffs) and \ if optimization and term_index+3 <= len(coeffs) and \
len(set(y for x in sites[term_index:term_index+3] for y in x ))==2 and\ len(set(y for x in sites[term_index:term_index+3] for y in x)) == 2 and\
set(pauli_words[term_index:term_index+3])=={'XX','YY','ZZ'}: set(pauli_words[term_index:term_index+3]) == {'XX', 'YY', 'ZZ'}:
optimal_circuit(circuit,[tau*i for i in coeffs[term_index:term_index+3]],sites[term_index]) optimal_circuit(circuit, [tau*i for i in coeffs[term_index:term_index+3]], sites[term_index])
term_index+=3 term_index += 3
else: else:
# get the sorted pauli_word and site (an array of qubit indices) according to their qubit indices # get the sorted pauli_word and site (an array of qubit indices) according to their qubit indices
pauli_word, site = __sort_pauli_word(pauli_words[term_index], sites[term_index]) pauli_word, site = __sort_pauli_word(pauli_words[term_index], sites[term_index])
add_n_pauli_gate(circuit, 2 * tau * coeffs[term_index], pauli_word, site) add_n_pauli_gate(circuit, 2 * tau * coeffs[term_index], pauli_word, site)
term_index+=1 term_index += 1
# in the reverse mode, if the Hamiltonian is a single element list, reverse the order its each term # in the reverse mode, if the Hamiltonian is a single element list, reverse the order its each term
else: else:
if len(grouped_hamiltonian) == 1: if len(grouped_hamiltonian) == 1:
...@@ -323,6 +326,31 @@ def __add_first_order_trotter_block(circuit, tau, grouped_hamiltonian, reverse=F ...@@ -323,6 +326,31 @@ def __add_first_order_trotter_block(circuit, tau, grouped_hamiltonian, reverse=F
add_n_pauli_gate(circuit, 2 * tau * coeffs[term_index], pauli_word, site) add_n_pauli_gate(circuit, 2 * tau * coeffs[term_index], pauli_word, site)
def optimal_circuit(circuit, theta, which_qubits):
r""" 添加一个优化电路,哈密顿量为'XXYYZZ'
Args:
circuit (UAnsatz): 需要添加门的电路
theta list(paddle.Tensor or float): 旋转角度需要传入三个参数
which_qubits (list or numpy.ndarray): ``pauli_word`` 中的每个算符所作用的量子比特编号
"""
p = np.pi/2
x, y, z = theta
alpha = paddle.to_tensor(3*p-4*x*p+2*x, dtype='float64')
beta = paddle.to_tensor(-3*p+4*y*p-2*y, dtype='float64')
gamma = paddle.to_tensor(2*z-p, dtype='float64')
which_qubits.sort()
a, b = which_qubits
circuit.rz(paddle.to_tensor(p, dtype='float64'), b)
circuit.cnot([b, a])
circuit.rz(gamma, a)
circuit.ry(alpha, b)
circuit.cnot([a, b])
circuit.ry(beta, b)
circuit.cnot([b, a])
circuit.rz(paddle.to_tensor(-p, dtype='float64'), a)
def __add_second_order_trotter_block(circuit, tau, grouped_hamiltonian): def __add_second_order_trotter_block(circuit, tau, grouped_hamiltonian):
r""" 添加二阶 trotter-suzuki 分解的时间演化块 r""" 添加二阶 trotter-suzuki 分解的时间演化块
...@@ -403,30 +431,7 @@ def add_n_pauli_gate(circuit, theta, pauli_word, which_qubits): ...@@ -403,30 +431,7 @@ def add_n_pauli_gate(circuit, theta, pauli_word, which_qubits):
circuit.h(which_qubits[qubit_index]) circuit.h(which_qubits[qubit_index])
elif re.match(r'Y', pauli_word[qubit_index], flags=re.I): elif re.match(r'Y', pauli_word[qubit_index], flags=re.I):
circuit.rx(- PI / 2, which_qubits[qubit_index]) circuit.rx(- PI / 2, which_qubits[qubit_index])
def optimal_circuit(circuit,theta,which_qubits):
r""" 添加一个优化电路,哈密顿量为'XXYYZZ'`
Args:
circuit (UAnsatz): 需要添加门的电路
theta list(tensor or float): 旋转角度需要传入三个参数
which_qubits (list or np.ndarray): ``pauli_word`` 中的每个算符所作用的量子比特编号
"""
p = np.pi/2
x,y,z = theta
alpha = paddle.to_tensor(3*p-4*x*p+2*x,dtype='float64')
beta = paddle.to_tensor(-3*p+4*y*p-2*y,dtype='float64')
gamma = paddle.to_tensor(2*z-p,dtype='float64')
which_qubits.sort()
a,b = which_qubits
circuit.rz(paddle.to_tensor(p,dtype='float64'),b)
circuit.cnot([b,a])
circuit.rz(gamma,a)
circuit.ry(alpha,b)
circuit.cnot([a,b])
circuit.ry(beta,b)
circuit.cnot([b,a])
circuit.rz(paddle.to_tensor(-p,dtype='float64'),a)
def __group_hamiltonian_xyz(hamiltonian): def __group_hamiltonian_xyz(hamiltonian):
r""" 将哈密顿量拆分成 X、Y、Z 以及剩余项四个部分,并返回由他们组成的列表 r""" 将哈密顿量拆分成 X、Y、Z 以及剩余项四个部分,并返回由他们组成的列表
...@@ -590,7 +595,6 @@ def get_1d_heisenberg_hamiltonian( ...@@ -590,7 +595,6 @@ def get_1d_heisenberg_hamiltonian(
boundary_sites = [0, length - 1] boundary_sites = [0, length - 1]
for interaction_idx in range(len(interactions)): for interaction_idx in range(len(interactions)):
term_str = '' term_str = ''
interaction = interactions[interaction_idx]
for idx_word in range(len(interaction)): for idx_word in range(len(interaction)):
term_str += interaction[idx_word] + str(boundary_sites[idx_word]) term_str += interaction[idx_word] + str(boundary_sites[idx_word])
if idx_word != len(interaction) - 1: if idx_word != len(interaction) - 1:
......
...@@ -20,6 +20,8 @@ import copy ...@@ -20,6 +20,8 @@ import copy
import re import re
import numpy as np import numpy as np
from scipy.linalg import logm, sqrtm from scipy.linalg import logm, sqrtm
from scipy.special import logsumexp
from tqdm import tqdm
from matplotlib import colors as mplcolors from matplotlib import colors as mplcolors
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import paddle import paddle
...@@ -34,10 +36,10 @@ import matplotlib as mpl ...@@ -34,10 +36,10 @@ import matplotlib as mpl
from paddle_quantum import simulator from paddle_quantum import simulator
import matplotlib.animation as animation import matplotlib.animation as animation
import matplotlib.image import matplotlib.image
from typing import Union, Optional
__all__ = [ __all__ = [
"partial_trace", "partial_trace",
"partial_trace_discontiguous",
"state_fidelity", "state_fidelity",
"trace_distance", "trace_distance",
"gate_fidelity", "gate_fidelity",
...@@ -57,11 +59,15 @@ __all__ = [ ...@@ -57,11 +59,15 @@ __all__ = [
"haar_unitary", "haar_unitary",
"haar_state_vector", "haar_state_vector",
"haar_density_operator", "haar_density_operator",
"Hamiltonian", "schmidt_decompose",
"plot_n_qubit_state_in_bloch_sphere",
"plot_state_in_bloch_sphere", "plot_state_in_bloch_sphere",
"plot_multi_qubits_state_in_bloch_sphere",
"plot_rotation_in_bloch_sphere", "plot_rotation_in_bloch_sphere",
"img_to_density_matrix", "plot_density_matrix_graph",
"image_to_density_matrix",
"Hamiltonian",
"QuantumFisher",
"ClassicalFisher",
] ]
...@@ -144,7 +150,7 @@ def partial_trace_discontiguous(rho, preserve_qubits=None): ...@@ -144,7 +150,7 @@ def partial_trace_discontiguous(rho, preserve_qubits=None):
result = np.zeros((2 ** num_preserve, 2 ** num_preserve), dtype="complex64") result = np.zeros((2 ** num_preserve, 2 ** num_preserve), dtype="complex64")
result = paddle.to_tensor(result) result = paddle.to_tensor(result)
for i in range(0, 2 ** num_preserve): for i in range(0, 2 ** (n - num_preserve)):
bra = identity[i * 2 ** num_preserve:(i + 1) * 2 ** num_preserve, :] bra = identity[i * 2 ** num_preserve:(i + 1) * 2 ** num_preserve, :]
result = result + matmul(matmul(bra, rho), transpose(bra, perm=[1, 0])) result = result + matmul(matmul(bra, rho), transpose(bra, perm=[1, 0]))
...@@ -244,10 +250,14 @@ def von_neumann_entropy(rho): ...@@ -244,10 +250,14 @@ def von_neumann_entropy(rho):
Returns: Returns:
float: 输入的量子态的冯诺依曼熵 float: 输入的量子态的冯诺依曼熵
""" """
rho_eigenvalue, _ = np.linalg.eig(rho) rho_eigenvalues = np.real(np.linalg.eigvals(rho))
entropy = -np.sum(rho_eigenvalue * np.log(rho_eigenvalue)) entropy = 0
for eigenvalue in rho_eigenvalues:
if np.abs(eigenvalue) < 1e-8:
continue
entropy -= eigenvalue * np.log(eigenvalue)
return entropy.real return entropy
def relative_entropy(rho, sig): def relative_entropy(rho, sig):
...@@ -281,7 +291,7 @@ def NKron(matrix_A, matrix_B, *args): ...@@ -281,7 +291,7 @@ def NKron(matrix_A, matrix_B, *args):
Tensor: 输入矩阵的Kronecker积 Tensor: 输入矩阵的Kronecker积
.. code-block:: python .. code-block:: python
from paddle_quantum.state import density_op_random from paddle_quantum.state import density_op_random
from paddle_quantum.utils import NKron from paddle_quantum.utils import NKron
A = density_op_random(2) A = density_op_random(2)
...@@ -306,7 +316,7 @@ def dagger(matrix): ...@@ -306,7 +316,7 @@ def dagger(matrix):
代码示例: 代码示例:
.. code-block:: python .. code-block:: python
from paddle_quantum.utils import dagger from paddle_quantum.utils import dagger
import numpy as np import numpy as np
rho = paddle.to_tensor(np.array([[1+1j, 2+2j], [3+3j, 4+4j]])) rho = paddle.to_tensor(np.array([[1+1j, 2+2j], [3+3j, 4+4j]]))
...@@ -641,1145 +651,1590 @@ def haar_density_operator(n, k=None, real=False): ...@@ -641,1145 +651,1590 @@ def haar_density_operator(n, k=None, real=False):
return rho / np.trace(rho) return rho / np.trace(rho)
class Hamiltonian: def schmidt_decompose(psi, sys_A=None):
r""" Paddle Quantum 中的 Hamiltonian ``class``。 r"""计算输入量子态的施密特分解 :math:`\lvert\psi\rangle=\sum_ic_i\lvert i_A\rangle\otimes\lvert i_B \rangle`。
用户可以通过一个 Pauli string 来实例化该 ``class``。 Args:
""" psi (numpy.ndarray): 量子态的向量形式,形状为(2**n)
def __init__(self, pauli_str, compress=True): sys_A (list): 包含在子系统 A 中的 qubit 下标(其余 qubit 包含在子系统B中),默认为量子态 :math:`\lvert \psi\rangle` 的前半数 qubit
r""" 创建一个 Hamiltonian 类。
Args: Returns:
pauli_str (list): 用列表定义的 Hamiltonian,如 ``[(1, 'Z0, Z1'), (2, 'I')]`` tuple: 包含如下元素
compress (bool): 是否对输入的 list 进行自动合并(例如 ``(1, 'Z0, Z1')`` 和 ``(2, 'Z1, Z0')`` 这两项将被自动合并),默认为 ``True`` - numpy.ndarray: 由施密特系数组成的一维数组,形状为 ``(k)``
- numpy.ndarray: 由子系统A的基 :math:`\lvert i_A\rangle` 组成的高维数组,形状为 ``(k, 2**m, 1)``
- numpy.ndarray: 由子系统B的基 :math:`\lvert i_B\rangle` 组成的高维数组,形状为 ``(k, 2**l, 1)``
Note: Warning:
如果设置 ``compress=False``,则不会对输入的合法性进行检验。 小于 ``1e-13`` 的施密特系数将被视作浮点误差并舍去
"""
self.__coefficients = None
self.__terms = None
self.__pauli_words_r = []
self.__pauli_words = []
self.__sites = []
self.__nqubits = None
# when internally updating the __pauli_str, be sure to set __update_flag to True
self.__pauli_str = pauli_str
self.__update_flag = True
self.__decompose()
if compress:
self.__compress()
def __getitem__(self, indices): .. code-block:: python
new_pauli_str = []
if isinstance(indices, int):
indices = [indices]
elif isinstance(indices, slice):
indices = list(range(self.n_terms)[indices])
elif isinstance(indices, tuple):
indices = list(indices)
for index in indices: # zz = 1/√2 * (<010| + <101|)
new_pauli_str.append([self.coefficients[index], ','.join(self.terms[index])]) zz = 1/np.sqrt(2) * (np.array([0., 0., 1., 0., 0., 0., 0., 0.]) + np.array([0., 0., 0., 0., 0., 1., 0., 0.]))
return Hamiltonian(new_pauli_str, compress=False) print('input state:', zz)
l, u, v = schmidt_decompose(zz, [0, 2])
def __add__(self, h_2): print('output state:')
new_pauli_str = self.pauli_str.copy() for i in range(len(l)):
if isinstance(h_2, float) or isinstance(h_2, int): print('+', l[i], '*', u[i].reshape([-1]), '⨂', v[i].reshape([-1]))
new_pauli_str.extend([[float(h_2), 'I']])
else:
new_pauli_str.extend(h_2.pauli_str)
return Hamiltonian(new_pauli_str)
def __mul__(self, other): Note:
new_pauli_str = copy.deepcopy(self.pauli_str) 代码示例结果应为 1/√2 * (<00|⨂<1| + <11|⨂<0|)。注意,输入态的第 0、2 个 qubit 处于输出态的子系统 A,输入态的第1个 qubit 处于输出态的子系统 B。
for i in range(len(new_pauli_str)): """
new_pauli_str[i][0] *= other
return Hamiltonian(new_pauli_str, compress=False)
def __sub__(self, other): assert psi.ndim == 1, 'Psi must be a one dimensional vector.'
return self.__add__(other.__mul__(-1)) assert np.log2(psi.size).is_integer(), 'The number of amplitutes must be an integral power of 2.'
def __str__(self): tot_qu = int(np.log2(psi.size))
str_out = '' sys_A = sys_A if sys_A is not None else [i for i in range(tot_qu//2)]
for idx in range(self.n_terms): sys_B = [i for i in range(tot_qu) if i not in sys_A]
str_out += '{} '.format(self.coefficients[idx])
for _ in range(len(self.terms[idx])):
str_out += self.terms[idx][_]
if _ != len(self.terms[idx]) - 1:
str_out += ', '
if idx != self.n_terms - 1:
str_out += '\n'
return str_out
def __repr__(self): # Permute qubit indices
return 'paddle_quantum.Hamiltonian object: \n' + self.__str__() psi = psi.reshape([2] * tot_qu).transpose(sys_A + sys_B)
@property # construct amplitute matrix
def n_terms(self): amp_mtr = psi.reshape([2**len(sys_A), 2**len(sys_B)])
r"""返回该哈密顿量的项数
Returns: # Standard process to obtain schmidt decomposition
int :哈密顿量的项数 u, c, v = np.linalg.svd(amp_mtr)
"""
return len(self.__pauli_str)
@property k = np.count_nonzero(c > 1e-13)
def pauli_str(self): c = c[:k]
r"""返回哈密顿量对应的 Pauli string u = u.T[:k].reshape([k, -1, 1])
v = v[:k].reshape([k, -1, 1])
return c, u, v
Returns:
list : 哈密顿量对应的 Pauli string
"""
return self.__pauli_str
@property def __density_matrix_convert_to_bloch_vector(density_matrix):
def terms(self): r"""该函数将密度矩阵转化为bloch球面上的坐标
r"""返回哈密顿量中的每一项构成的列表
Returns: Args:
list :哈密顿量中的每一项,i.e. ``[['Z0, Z1'], ['I']]`` density_matrix (numpy.ndarray): 输入的密度矩阵
"""
if self.__update_flag:
self.__decompose()
return self.__terms
else:
return self.__terms
@property Returns:
def coefficients(self): bloch_vector (numpy.ndarray): 存储bloch向量的 x,y,z 坐标,向量的模长,向量的颜色
r""" 返回哈密顿量中的每一项对应的系数构成的列表 """
Returns: # Pauli Matrix
list :哈密顿量中每一项的系数,i.e. ``[1.0, 2.0]`` pauli_x = np.array([[0, 1], [1, 0]])
""" pauli_y = np.array([[0, -1j], [1j, 0]])
if self.__update_flag: pauli_z = np.array([[1, 0], [0, -1]])
self.__decompose()
return self.__coefficients
else:
return self.__coefficients
@property # Convert a density matrix to a Bloch vector.
def pauli_words(self): ax = np.trace(np.dot(density_matrix, pauli_x)).real
r"""返回哈密顿量中每一项对应的 Pauli word 构成的列表 ay = np.trace(np.dot(density_matrix, pauli_y)).real
az = np.trace(np.dot(density_matrix, pauli_z)).real
Returns: # Calc the length of bloch vector
list :每一项对应的 Pauli word,i.e. ``['ZIZ', 'IIX']`` length = ax ** 2 + ay ** 2 + az ** 2
""" length = sqrt(length)
if self.__update_flag: if length > 1.0:
self.__decompose() length = 1.0
return self.__pauli_words
else:
return self.__pauli_words
@property # Calc the color of bloch vector, the value of the color is proportional to the length
def pauli_words_r(self): color = length
r"""返回哈密顿量中每一项对应的简化(不包含 I) Pauli word 组成的列表
Returns: bloch_vector = [ax, ay, az, length, color]
list :不包含 "I" 的 Pauli word 构成的列表,i.e. ``['ZXZZ', 'Z', 'X']``
"""
if self.__update_flag:
self.__decompose()
return self.__pauli_words_r
else:
return self.__pauli_words_r
@property # You must use an array, which is followed by slicing and taking a column
def sites(self): bloch_vector = np.array(bloch_vector)
r"""返回该哈密顿量中的每一项对应的量子比特编号组成的列表
Returns: return bloch_vector
list :哈密顿量中每一项所对应的量子比特编号构成的列表,i.e. ``[[1, 2], [0]]``
"""
if self.__update_flag:
self.__decompose()
return self.__sites
else:
return self.__sites
@property
def n_qubits(self):
r"""返回该哈密顿量对应的量子比特数
Returns: def __plot_bloch_sphere(
int :量子比特数 ax,
""" bloch_vectors=None,
if self.__update_flag: show_arrow=False,
self.__decompose() clear_plt=True,
return self.__nqubits rotating_angle_list=None,
else: view_angle=None,
return self.__nqubits view_dist=None,
set_color=None
):
r"""将 Bloch 向量展示在 Bloch 球面上
def __decompose(self): Args:
r"""将哈密顿量分解为不同的形式 ax (Axes3D(fig)): 画布的句柄
bloch_vectors (numpy.ndarray): 存储bloch向量的 x,y,z 坐标,向量的模长,向量的颜色
show_arrow (bool): 是否展示向量的箭头,默认为 False
clear_plt (bool): 是否要清空画布,默认为 True,每次画图的时候清空画布再画图
rotating_angle_list (list): 旋转角度的列表,用于展示旋转轨迹
view_angle (list): 视图的角度,
第一个元素为关于xy平面的夹角[0-360],第二个元素为关于xz平面的夹角[0-360], 默认为 (30, 45)
view_dist (int): 视图的距离,默认为 7
set_color (str): 设置指定的颜色,请查阅cmap表,默认为 "红-黑-根据向量的模长渐变" 颜色方案
"""
# Assign a value to an empty variable
if view_angle is None:
view_angle = (30, 45)
if view_dist is None:
view_dist = 7
# Define my_color
if set_color is None:
color = 'rainbow'
black_code = '#000000'
red_code = '#F24A29'
if bloch_vectors is not None:
black_to_red = mplcolors.LinearSegmentedColormap.from_list(
'my_color',
[(0, black_code), (1, red_code)],
N=len(bloch_vectors[:, 4])
)
map_vir = plt.get_cmap(black_to_red)
color = map_vir(bloch_vectors[:, 4])
else:
color = set_color
Notes: # Set the view angle and view distance
这是一个内部函数,你不需要直接使用它 ax.view_init(view_angle[0], view_angle[1])
这是一个比较基础的函数,它负责将输入的 Pauli string 拆分为不同的形式并存储在内部变量中 ax.dist = view_dist
"""
self.__pauli_words = []
self.__pauli_words_r = []
self.__sites = []
self.__terms = []
self.__coefficients = []
self.__nqubits = 1
new_pauli_str = []
for coefficient, pauli_term in self.__pauli_str:
pauli_word_r = ''
site = []
single_pauli_terms = re.split(r',\s*', pauli_term.upper())
self.__coefficients.append(float(coefficient))
self.__terms.append(single_pauli_terms)
for single_pauli_term in single_pauli_terms:
match_I = re.match(r'I', single_pauli_term, flags=re.I)
if match_I:
assert single_pauli_term[0].upper() == 'I', \
'The offset is defined with a sole letter "I", i.e. (3.0, "I")'
pauli_word_r += 'I'
site.append('')
else:
match = re.match(r'([XYZ])([0-9]+)', single_pauli_term, flags=re.I)
if match:
pauli_word_r += match.group(1).upper()
assert int(match.group(2)) not in site, 'each Pauli operator should act on different qubit'
site.append(int(match.group(2)))
else:
raise Exception(
'Operators should be defined with a string composed of Pauli operators followed' +
'by qubit index on which it act, separated with ",". i.e. "Z0, X1"')
self.__nqubits = max(self.__nqubits, int(match.group(2)) + 1)
self.__pauli_words_r.append(pauli_word_r)
self.__sites.append(site)
new_pauli_str.append([float(coefficient), pauli_term.upper()])
for term_index in range(len(self.__pauli_str)):
pauli_word = ['I' for _ in range(self.__nqubits)]
site = self.__sites[term_index]
for site_index in range(len(site)):
if type(site[site_index]) == int:
pauli_word[site[site_index]] = self.__pauli_words_r[term_index][site_index]
self.__pauli_words.append(''.join(pauli_word))
self.__pauli_str = new_pauli_str
self.__update_flag = False
def __compress(self):
r""" 对同类项进行合并。
Notes:
这是一个内部函数,你不需要直接使用它
"""
if self.__update_flag:
self.__decompose()
else:
pass
new_pauli_str = []
flag_merged = [False for _ in range(self.n_terms)]
for term_idx_1 in range(self.n_terms):
if not flag_merged[term_idx_1]:
for term_idx_2 in range(term_idx_1 + 1, self.n_terms):
if not flag_merged[term_idx_2]:
if self.pauli_words[term_idx_1] == self.pauli_words[term_idx_2]:
self.__coefficients[term_idx_1] += self.__coefficients[term_idx_2]
flag_merged[term_idx_2] = True
else:
pass
if self.__coefficients[term_idx_1] != 0:
new_pauli_str.append([self.__coefficients[term_idx_1], ','.join(self.__terms[term_idx_1])])
self.__pauli_str = new_pauli_str
self.__update_flag = True
def decompose_with_sites(self): # Draw the general frame
r"""将 pauli_str 分解为系数、泡利字符串的简化形式以及它们分别作用的量子比特下标。 def draw_general_frame():
Returns: # Do not show the grid and original axes
tuple: 包含如下元素的 tuple: ax.grid(False)
ax.set_axis_off()
ax.view_init(view_angle[0], view_angle[1])
ax.dist = view_dist
- coefficients (list): 元素为每一项的系数 # Set the lower limit and upper limit of each axis
- pauli_words_r (list): 元素为每一项的泡利字符串的简化形式,例如 'Z0, Z1, X3' 这一项的泡利字符串为 'ZZX' # To make the bloch_ball look less flat, the default is relatively flat
- sites (list): 元素为每一项作用的量子比特下标,例如 'Z0, Z1, X3' 这一项的 site 为 [0, 1, 3] ax.set_xlim3d(xmin=-1.5, xmax=1.5)
ax.set_ylim3d(ymin=-1.5, ymax=1.5)
ax.set_zlim3d(zmin=-1, zmax=1.3)
""" # Draw a new axes
if self.__update_flag: coordinate_start_x, coordinate_start_y, coordinate_start_z = \
self.__decompose() np.array([[-1.5, 0, 0], [0, -1.5, 0], [0, 0, -1.5]])
return self.coefficients, self.__pauli_words_r, self.__sites coordinate_end_x, coordinate_end_y, coordinate_end_z = \
np.array([[3, 0, 0], [0, 3, 0], [0, 0, 3]])
ax.quiver(
coordinate_start_x, coordinate_start_y, coordinate_start_z,
coordinate_end_x, coordinate_end_y, coordinate_end_z,
arrow_length_ratio=0.03, color="black", linewidth=0.5
)
ax.text(0, 0, 1.7, r"|0⟩", color="black", fontsize=16)
ax.text(0, 0, -1.9, r"|1⟩", color="black", fontsize=16)
ax.text(1.9, 0, 0, r"|+⟩", color="black", fontsize=16)
ax.text(-1.7, 0, 0, r"|–⟩", color="black", fontsize=16)
ax.text(0, 1.7, 0, r"|i+⟩", color="black", fontsize=16)
ax.text(0, -1.9, 0, r"|i–⟩", color="black", fontsize=16)
def decompose_pauli_words(self): # Draw a surface
r"""将 pauli_str 分解为系数和泡利字符串。 horizontal_angle = np.linspace(0, 2 * np.pi, 80)
vertical_angle = np.linspace(0, np.pi, 80)
surface_point_x = np.outer(np.cos(horizontal_angle), np.sin(vertical_angle))
surface_point_y = np.outer(np.sin(horizontal_angle), np.sin(vertical_angle))
surface_point_z = np.outer(np.ones(np.size(horizontal_angle)), np.cos(vertical_angle))
ax.plot_surface(
surface_point_x, surface_point_y, surface_point_z, rstride=1, cstride=1,
color="black", linewidth=0.05, alpha=0.03
)
Returns: # Draw circle
tuple: 包含如下元素的 tuple: def draw_circle(circle_horizon_angle, circle_vertical_angle, linewidth=0.5, alpha=0.2):
r = 1
circle_point_x = r * np.cos(circle_vertical_angle) * np.cos(circle_horizon_angle)
circle_point_y = r * np.cos(circle_vertical_angle) * np.sin(circle_horizon_angle)
circle_point_z = r * np.sin(circle_vertical_angle)
ax.plot(
circle_point_x, circle_point_y, circle_point_z,
color="black", linewidth=linewidth, alpha=alpha
)
- coefficients(list): 元素为每一项的系数 # draw longitude and latitude
- pauli_words(list): 元素为每一项的泡利字符串,例如 'Z0, Z1, X3' 这一项的泡利字符串为 'ZZIX' def draw_longitude_and_latitude():
""" # Draw longitude
if self.__update_flag: num = 3
self.__decompose() theta = np.linspace(0, 0, 100)
else: psi = np.linspace(0, 2 * np.pi, 100)
pass for i in range(num):
return self.coefficients, self.__pauli_words theta = theta + np.pi / num
draw_circle(theta, psi)
def construct_h_matrix(self, n_qubit=None): # Draw latitude
r"""构建 Hamiltonian 在 Z 基底下的矩阵。 num = 6
theta = np.linspace(0, 2 * np.pi, 100)
psi = np.linspace(-np.pi / 2, -np.pi / 2, 100)
for i in range(num):
psi = psi + np.pi / num
draw_circle(theta, psi)
Returns: # Draw equator
np.ndarray: Z 基底下的哈密顿量矩阵形式 theta = np.linspace(0, 2 * np.pi, 100)
""" psi = np.linspace(0, 0, 100)
coefs, pauli_words, sites = self.decompose_with_sites() draw_circle(theta, psi, linewidth=0.5, alpha=0.2)
if n_qubit is None:
n_qubit = 1
for site in sites:
if type(site[0]) is int:
print(n_qubit,(site))
n_qubit = max(n_qubit, max(site) + 1)
else:
assert n_qubit>=self.n_qubits,"输入的量子数不小于哈密顿量表达式中所对应的量子比特数"
h_matrix = np.zeros([2 ** n_qubit, 2 ** n_qubit], dtype='complex64')
spin_ops = SpinOps(n_qubit, use_sparse=True)
for idx in range(len(coefs)):
op = coefs[idx] * sparse.eye(2 ** n_qubit, dtype='complex64')
for site_idx in range(len(sites[idx])):
if re.match(r'X', pauli_words[idx][site_idx], re.I):
op = op.dot(spin_ops.sigx_p[sites[idx][site_idx]])
elif re.match(r'Y', pauli_words[idx][site_idx], re.I):
op = op.dot(spin_ops.sigy_p[sites[idx][site_idx]])
elif re.match(r'Z', pauli_words[idx][site_idx], re.I):
op = op.dot(spin_ops.sigz_p[sites[idx][site_idx]])
h_matrix += op
return h_matrix
# Draw prime meridian
theta = np.linspace(0, 0, 100)
psi = np.linspace(0, 2 * np.pi, 100)
draw_circle(theta, psi, linewidth=0.5, alpha=0.2)
class SpinOps: # If the number of data points exceeds 20, no longitude and latitude lines will be drawn.
r"""矩阵表示下的自旋算符,可以用来构建哈密顿量矩阵或者自旋可观测量。 if bloch_vectors is not None and len(bloch_vectors) < 52:
draw_longitude_and_latitude()
elif bloch_vectors is None:
draw_longitude_and_latitude()
""" # Draw three invisible points
def __init__(self, size: int, use_sparse=False): invisible_points = np.array([[0.03440399, 0.30279721, 0.95243384],
r"""SpinOps 的构造函数,用于实例化一个 SpinOps 对象。 [0.70776026, 0.57712403, 0.40743499],
[0.46991358, -0.63717908, 0.61088792]])
ax.scatter(
invisible_points[:, 0], invisible_points[:, 1], invisible_points[:, 2],
c='w', alpha=0.01
)
Args: # clean plt
size (int): 系统的大小(有几个量子比特) if clear_plt:
use_sparse (bool): 是否使用 sparse matrix 计算,默认为 ``False`` ax.cla()
""" draw_general_frame()
self.size = size
self.id = sparse.eye(2, dtype='complex128')
self.__sigz = sparse.bsr.bsr_matrix([[1, 0], [0, -1]], dtype='complex64')
self.__sigy = sparse.bsr.bsr_matrix([[0, -1j], [1j, 0]], dtype='complex64')
self.__sigx = sparse.bsr.bsr_matrix([[0, 1], [1, 0]], dtype='complex64')
self.__sigz_p = []
self.__sigy_p = []
self.__sigx_p = []
self.__sparse = use_sparse
for i in range(self.size):
self.__sigz_p.append(self.__direct_prod_op(spin_op=self.__sigz, spin_index=i))
self.__sigy_p.append(self.__direct_prod_op(spin_op=self.__sigy, spin_index=i))
self.__sigx_p.append(self.__direct_prod_op(spin_op=self.__sigx, spin_index=i))
@property # Draw the data points
def sigz_p(self): if bloch_vectors is not None:
r""" :math:`Z` 基底下的 :math:`S^z_i` 算符。 ax.scatter(
bloch_vectors[:, 0], bloch_vectors[:, 1], bloch_vectors[:, 2], c=color, alpha=1.0
)
Returns: # if show the rotating angle
list : :math:`S^z_i` 算符组成的列表,其中每一项对应不同的 :math:`i` if rotating_angle_list is not None:
""" bloch_num = len(bloch_vectors)
return self.__sigz_p rotating_angle_theta, rotating_angle_phi, rotating_angle_lam = rotating_angle_list[bloch_num - 1]
rotating_angle_theta = round(rotating_angle_theta, 6)
rotating_angle_phi = round(rotating_angle_phi, 6)
rotating_angle_lam = round(rotating_angle_lam, 6)
@property # Shown at the top right of the perspective
def sigy_p(self): display_text_angle = [-(view_angle[0] - 10), (view_angle[1] + 10)]
r""" :math:`Z` 基底下的 :math:`S^y_i` 算符。 text_point_x = 2 * np.cos(display_text_angle[0]) * np.cos(display_text_angle[1])
text_point_y = 2 * np.cos(display_text_angle[0]) * np.sin(-display_text_angle[1])
text_point_z = 2 * np.sin(-display_text_angle[0])
ax.text(text_point_x, text_point_y, text_point_z, r'$\theta=' + str(rotating_angle_theta) + r'$',
color="black", fontsize=14)
ax.text(text_point_x, text_point_y, text_point_z - 0.1, r'$\phi=' + str(rotating_angle_phi) + r'$',
color="black", fontsize=14)
ax.text(text_point_x, text_point_y, text_point_z - 0.2, r'$\lambda=' + str(rotating_angle_lam) + r'$',
color="black", fontsize=14)
Returns: # If show the bloch_vector
list : :math:`S^y_i` 算符组成的列表,其中每一项对应不同的 :math:`i` if show_arrow:
""" ax.quiver(
return self.__sigy_p 0, 0, 0, bloch_vectors[:, 0], bloch_vectors[:, 1], bloch_vectors[:, 2],
arrow_length_ratio=0.05, color=color, alpha=1.0
)
@property
def sigx_p(self):
r""" :math:`Z` 基底下的 :math:`S^x_i` 算符。
Returns: def plot_state_in_bloch_sphere(
list : :math:`S^x_i` 算符组成的列表,其中每一项对应不同的 :math:`i` state,
""" show_arrow=False,
return self.__sigx_p save_gif=False,
filename=None,
def __direct_prod_op(self, spin_op, spin_index): view_angle=None,
r"""直积,得到第 n 个自旋(量子比特)上的自旋算符 view_dist=None,
set_color=None
Args: ):
spin_op: 单体自旋算符 r"""将输入的量子态展示在 Bloch 球面上
spin_index: 标记第 n 个自旋(量子比特)
Returns:
scipy.sparse or np.ndarray: 直积后的自旋算符,其数据类型取决于 self.__use_sparse
"""
s_p = copy.copy(spin_op)
for i in range(self.size):
if i < spin_index:
s_p = sparse.kron(self.id, s_p)
elif i > spin_index:
s_p = sparse.kron(s_p, self.id)
if self.__sparse:
return s_p
else:
return s_p.toarray()
def __input_args_dtype_check(
show_arrow,
save_gif,
filename,
view_angle,
view_dist
):
r"""
该函数实现对输入默认参数的数据类型检查,保证输入函数中的参数为所允许的数据类型
Args: Args:
show_arrow (bool): 是否展示向量的箭头,默认为 False state (list(numpy.ndarray or paddle.Tensor)): 输入的量子态列表,可以支持态矢量和密度矩阵
save_gif (bool): 是否存储 gif 动图 show_arrow (bool): 是否展示向量的箭头,默认为 ``False``
save_gif (bool): 是否存储 gif 动图,默认为 ``False``
filename (str): 存储的 gif 动图的名字 filename (str): 存储的 gif 动图的名字
view_angle (list or tuple): 视图的角度, view_angle (list or tuple): 视图的角度,
第一个元素为关于xy平面的夹角[0-360],第二个元素为关于xz平面的夹角[0-360], 默认为 (30, 45) 第一个元素为关于 xy 平面的夹角 [0-360],第二个元素为关于 xz 平面的夹角 [0-360], 默认为 ``(30, 45)``
view_dist (int): 视图的距离,默认为 7 view_dist (int): 视图的距离,默认为 7
set_color (str): 若要设置指定的颜色,请查阅 ``cmap`` 表。默认为红色到黑色的渐变颜色
""" """
# Check input data
__input_args_dtype_check(show_arrow, save_gif, filename, view_angle, view_dist)
if show_arrow is not None: assert type(state) == list or type(state) == paddle.Tensor or type(state) == np.ndarray, \
assert type(show_arrow) == bool, \ 'the type of "state" must be "list" or "paddle.Tensor" or "np.ndarray".'
'the type of "show_arrow" should be "bool".' if type(state) == paddle.Tensor or type(state) == np.ndarray:
if save_gif is not None: state = [state]
assert type(save_gif) == bool, \ state_len = len(state)
'the type of "save_gif" should be "bool".' assert state_len >= 1, '"state" is NULL.'
if save_gif: for i in range(state_len):
if filename is not None: assert type(state[i]) == paddle.Tensor or type(state[i]) == np.ndarray, \
assert type(filename) == str, \ 'the type of "state[i]" should be "paddle.Tensor" or "numpy.ndarray".'
'the type of "filename" should be "str".' if set_color is not None:
other, ext = os.path.splitext(filename) assert type(set_color) == str, \
assert ext == '.gif', 'The suffix of the file name must be "gif".' 'the type of "set_color" should be "str".'
# If it does not exist, create a folder
path, file = os.path.split(filename)
if not os.path.exists(path):
os.makedirs(path)
if view_angle is not None:
assert type(view_angle) == list or type(view_angle) == tuple, \
'the type of "view_angle" should be "list" or "tuple".'
for i in range(2):
assert type(view_angle[i]) == int, \
'the type of "view_angle[0]" and "view_angle[1]" should be "int".'
if view_dist is not None:
assert type(view_dist) == int, \
'the type of "view_dist" should be "int".'
# Assign a value to an empty variable
if filename is None:
filename = 'state_in_bloch_sphere.gif'
if view_angle is None:
view_angle = (30, 45)
if view_dist is None:
view_dist = 7
def __density_matrix_convert_to_bloch_vector(density_matrix): # Convert Tensor to numpy
r"""该函数将密度矩阵转化为bloch球面上的坐标 for i in range(state_len):
if type(state[i]) == paddle.Tensor:
state[i] = state[i].numpy()
Args: # Convert state_vector to density_matrix
density_matrix (numpy.ndarray): 输入的密度矩阵 for i in range(state_len):
if state[i].size == 2:
state_vector = state[i]
state[i] = np.outer(state_vector, np.conj(state_vector))
Returns: # Calc the bloch_vectors
bloch_vector (numpy.ndarray): 存储bloch向量的 x,y,z 坐标,向量的模长,向量的颜色 bloch_vector_list = []
""" for i in range(state_len):
bloch_vector_tmp = __density_matrix_convert_to_bloch_vector(state[i])
bloch_vector_list.append(bloch_vector_tmp)
# Pauli Matrix # List must be converted to array for slicing.
pauli_x = np.array([[0, 1], [1, 0]]) bloch_vectors = np.array(bloch_vector_list)
pauli_y = np.array([[0, -1j], [1j, 0]])
pauli_z = np.array([[1, 0], [0, -1]])
# Convert a density matrix to a Bloch vector. # A update function for animation class
ax = np.trace(np.dot(density_matrix, pauli_x)).real def update(frame):
ay = np.trace(np.dot(density_matrix, pauli_y)).real view_rotating_angle = 5
az = np.trace(np.dot(density_matrix, pauli_z)).real new_view_angle = [view_angle[0], view_angle[1] + view_rotating_angle * frame]
__plot_bloch_sphere(
ax, bloch_vectors, show_arrow, clear_plt=True,
view_angle=new_view_angle, view_dist=view_dist, set_color=set_color
)
# Calc the length of bloch vector # Dynamic update and save
length = ax ** 2 + ay ** 2 + az ** 2 if save_gif:
length = sqrt(length) # Helper function to plot vectors on a sphere.
if length > 1.0: fig = plt.figure(figsize=(8, 8), dpi=100)
length = 1.0 fig.subplots_adjust(left=0, right=1, bottom=0, top=1)
ax = fig.add_subplot(111, projection='3d')
# Calc the color of bloch vector, the value of the color is proportional to the length frames_num = 7
color = length anim = animation.FuncAnimation(fig, update, frames=frames_num, interval=600, repeat=False)
anim.save(filename, dpi=100, writer='pillow')
# close the plt
plt.close(fig)
bloch_vector = [ax, ay, az, length, color] # Helper function to plot vectors on a sphere.
fig = plt.figure(figsize=(8, 8), dpi=100)
fig.subplots_adjust(left=0, right=1, bottom=0, top=1)
ax = fig.add_subplot(111, projection='3d')
# You must use an array, which is followed by slicing and taking a column __plot_bloch_sphere(
bloch_vector = np.array(bloch_vector) ax, bloch_vectors, show_arrow, clear_plt=True,
view_angle=view_angle, view_dist=view_dist, set_color=set_color
)
return bloch_vector plt.show()
def __plot_bloch_sphere( def plot_multi_qubits_state_in_bloch_sphere(
ax, state,
bloch_vectors=None, which_qubits=None,
show_arrow=False, show_arrow=False,
clear_plt=True, save_gif=False,
rotating_angle_list=None, save_pic=True,
filename=None,
view_angle=None, view_angle=None,
view_dist=None, view_dist=None,
set_color=None set_color='#0000FF'
): ):
r"""将 Bloch 向量展示在 Bloch 球面上 r"""将输入的多量子比特的量子态展示在 Bloch 球面上
Args: Args:
ax (Axes3D(fig)): 画布的句柄 state (numpy.ndarray or paddle.Tensor): 输入的量子态,可以支持态矢量和密度矩阵
bloch_vectors (numpy.ndarray): 存储bloch向量的 x,y,z 坐标,向量的模长,向量的颜色 which_qubits (list or None): 要展示的量子比特,默认为全展示
show_arrow (bool): 是否展示向量的箭头,默认为 False show_arrow (bool): 是否展示向量的箭头,默认为 ``False``
clear_plt (bool): 是否要清空画布,默认为 True,每次画图的时候清空画布再画图 save_gif (bool): 是否存储 gif 动图,默认为 ``False``
rotating_angle_list (list): 旋转角度的列表,用于展示旋转轨迹 save_pic (bool): 是否存储静态图片,默认为 ``True``
view_angle (list): 视图的角度, filename (str): 存储的图片的名字
第一个元素为关于xy平面的夹角[0-360],第二个元素为关于xz平面的夹角[0-360], 默认为 (30, 45) view_angle (list or tuple): 视图的角度,第一个元素为关于 xy 平面的夹角 [0-360],第二个元素为关于 xz 平面的夹角 [0-360], 默认为 ``(30, 45)``
view_dist (int): 视图的距离,默认为 7 view_dist (int): 视图的距离,默认为 7
set_color (str): 设置指定的颜色,请查阅cmap表,默认为 "红-黑-根据向量的模长渐变" 颜色方案 set_color (str): 若要设置指定的颜色,请查阅 ``cmap`` 表。默认为蓝色
""" """
# Check input data
__input_args_dtype_check(show_arrow, save_gif, filename, view_angle, view_dist)
assert type(state) == paddle.Tensor or type(state) == np.ndarray, \
'the type of "state" must be "paddle.Tensor" or "np.ndarray".'
assert type(set_color) == str, \
'the type of "set_color" should be "str".'
n_qubits = int(np.log2(state.shape[0]))
if which_qubits is None:
which_qubits = list(range(n_qubits))
else:
assert type(which_qubits) == list, 'the type of which_qubits should be None or list'
assert 1 <= len(which_qubits) <= n_qubits, '展示的量子数量需要小于n_qubits'
for i in range(len(which_qubits)):
assert 0 <= which_qubits[i] < n_qubits, '0<which_qubits[i]<n_qubits'
# Assign a value to an empty variable # Assign a value to an empty variable
if filename is None:
filename = 'state_in_bloch_sphere.gif'
if view_angle is None: if view_angle is None:
view_angle = (30, 45) view_angle = (30, 45)
if view_dist is None: if view_dist is None:
view_dist = 7 view_dist = 7
# Define my_color
if set_color is None:
color = 'rainbow'
black_code = '#000000'
red_code = '#F24A29'
if bloch_vectors is not None:
black_to_red = mplcolors.LinearSegmentedColormap.from_list(
'my_color',
[(0, black_code), (1, red_code)],
N=len(bloch_vectors[:, 4])
)
map_vir = plt.get_cmap(black_to_red)
color = map_vir(bloch_vectors[:, 4])
else:
color = set_color
# Set the view angle and view distance # Convert Tensor to numpy
ax.view_init(view_angle[0], view_angle[1]) if type(state) == paddle.Tensor:
ax.dist = view_dist state = state.numpy()
# Draw the general frame # state_vector to density matrix
def draw_general_frame(): if state.shape[0] >= 2 and state.size == state.shape[0]:
state_vector = state
state = np.outer(state_vector, np.conj(state_vector))
# Do not show the grid and original axes # multi qubits state decompose
ax.grid(False) if state.shape[0] > 2:
ax.set_axis_off() rho = paddle.to_tensor(state)
ax.view_init(view_angle[0], view_angle[1]) tmp_s = []
ax.dist = view_dist for q in which_qubits:
tmp_s.append(partial_trace_discontiguous(rho, [q]))
state = tmp_s
else:
state = [state]
state_len = len(state)
# Set the lower limit and upper limit of each axis # Calc the bloch_vectors
# To make the bloch_ball look less flat, the default is relatively flat bloch_vector_list = []
ax.set_xlim3d(xmin=-1.5, xmax=1.5) for i in range(state_len):
ax.set_ylim3d(ymin=-1.5, ymax=1.5) bloch_vector_tmp = __density_matrix_convert_to_bloch_vector(state[i])
ax.set_zlim3d(zmin=-1, zmax=1.3) bloch_vector_list.append(bloch_vector_tmp)
# Draw a new axes # List must be converted to array for slicing.
coordinate_start_x, coordinate_start_y, coordinate_start_z = \ bloch_vectors = np.array(bloch_vector_list)
np.array([[-1.5, 0, 0], [0, -1.5, 0], [0, 0, -1.5]])
coordinate_end_x, coordinate_end_y, coordinate_end_z = \
np.array([[3, 0, 0], [0, 3, 0], [0, 0, 3]])
ax.quiver(
coordinate_start_x, coordinate_start_y, coordinate_start_z,
coordinate_end_x, coordinate_end_y, coordinate_end_z,
arrow_length_ratio=0.03, color="black", linewidth=0.5
)
ax.text(0, 0, 1.7, r"|0⟩", color="black", fontsize=16)
ax.text(0, 0, -1.9, r"|1⟩", color="black", fontsize=16)
ax.text(1.9, 0, 0, r"|+⟩", color="black", fontsize=16)
ax.text(-1.7, 0, 0, r"|–⟩", color="black", fontsize=16)
ax.text(0, 1.7, 0, r"|i+⟩", color="black", fontsize=16)
ax.text(0, -1.9, 0, r"|i–⟩", color="black", fontsize=16)
# Draw a surface # A update function for animation class
horizontal_angle = np.linspace(0, 2 * np.pi, 80) def update(frame):
vertical_angle = np.linspace(0, np.pi, 80) view_rotating_angle = 5
surface_point_x = np.outer(np.cos(horizontal_angle), np.sin(vertical_angle)) new_view_angle = [view_angle[0], view_angle[1] + view_rotating_angle * frame]
surface_point_y = np.outer(np.sin(horizontal_angle), np.sin(vertical_angle)) __plot_bloch_sphere(
surface_point_z = np.outer(np.ones(np.size(horizontal_angle)), np.cos(vertical_angle)) ax, bloch_vectors, show_arrow, clear_plt=True,
ax.plot_surface( view_angle=new_view_angle, view_dist=view_dist, set_color=set_color
surface_point_x, surface_point_y, surface_point_z, rstride=1, cstride=1,
color="black", linewidth=0.05, alpha=0.03
) )
# Draw circle # Dynamic update and save
def draw_circle(circle_horizon_angle, circle_vertical_angle, linewidth=0.5, alpha=0.2): if save_gif:
r = 1 # Helper function to plot vectors on a sphere.
circle_point_x = r * np.cos(circle_vertical_angle) * np.cos(circle_horizon_angle) fig = plt.figure(figsize=(8, 8), dpi=100)
circle_point_y = r * np.cos(circle_vertical_angle) * np.sin(circle_horizon_angle) fig.subplots_adjust(left=0, right=1, bottom=0, top=1)
circle_point_z = r * np.sin(circle_vertical_angle) ax = fig.add_subplot(111, projection='3d')
ax.plot(
circle_point_x, circle_point_y, circle_point_z,
color="black", linewidth=linewidth, alpha=alpha
)
# draw longitude and latitude frames_num = 7
def draw_longitude_and_latitude(): anim = animation.FuncAnimation(fig, update, frames=frames_num, interval=600, repeat=False)
# Draw longitude anim.save(filename, dpi=100, writer='pillow')
num = 3 # close the plt
theta = np.linspace(0, 0, 100) plt.close(fig)
psi = np.linspace(0, 2 * np.pi, 100)
for i in range(num):
theta = theta + np.pi / num
draw_circle(theta, psi)
# Draw latitude # Helper function to plot vectors on a sphere.
num = 6 fig = plt.figure(figsize=(8, 8), dpi=100)
theta = np.linspace(0, 2 * np.pi, 100) fig.subplots_adjust(left=0, right=1, bottom=0, top=1)
psi = np.linspace(-np.pi / 2, -np.pi / 2, 100) dim = np.ceil(sqrt(len(which_qubits)))
for i in range(num): for i in range(1, len(which_qubits)+1):
psi = psi + np.pi / num ax = fig.add_subplot(dim, dim, i, projection='3d')
draw_circle(theta, psi) bloch_vector = np.array([bloch_vectors[i-1]])
__plot_bloch_sphere(
ax, bloch_vector, show_arrow, clear_plt=True,
view_angle=view_angle, view_dist=view_dist, set_color=set_color
)
if save_pic:
plt.savefig('n_qubit_state_in_bloch.png', bbox_inches='tight')
plt.show()
# Draw equator
theta = np.linspace(0, 2 * np.pi, 100)
psi = np.linspace(0, 0, 100)
draw_circle(theta, psi, linewidth=0.5, alpha=0.2)
# Draw prime meridian def plot_rotation_in_bloch_sphere(
theta = np.linspace(0, 0, 100) init_state,
psi = np.linspace(0, 2 * np.pi, 100) rotating_angle,
draw_circle(theta, psi, linewidth=0.5, alpha=0.2) show_arrow=False,
save_gif=False,
filename=None,
view_angle=None,
view_dist=None,
color_scheme=None,
):
r"""在 Bloch 球面上刻画从初始量子态开始的旋转轨迹
# If the number of data points exceeds 20, no longitude and latitude lines will be drawn. Args:
if bloch_vectors is not None and len(bloch_vectors) < 52: init_state (numpy.ndarray or paddle.Tensor): 输入的初始量子态,可以支持态矢量和密度矩阵
draw_longitude_and_latitude() rotating_angle (list(float)): 旋转角度 ``[theta, phi, lam]``
elif bloch_vectors is None: show_arrow (bool): 是否展示向量的箭头,默认为 ``False``
draw_longitude_and_latitude() save_gif (bool): 是否存储 gif 动图,默认为 ``False``
filename (str): 存储的 gif 动图的名字
view_angle (list or tuple): 视图的角度,
第一个元素为关于 xy 平面的夹角 [0-360],第二个元素为关于 xz 平面的夹角 [0-360], 默认为 ``(30, 45)``
view_dist (int): 视图的距离,默认为 7
color_scheme (list(str,str,str)): 分别是初始颜色,轨迹颜色,结束颜色。若要设置指定的颜色,请查阅 ``cmap`` 表。默认为红色
"""
# Check input data
__input_args_dtype_check(show_arrow, save_gif, filename, view_angle, view_dist)
# Draw three invisible points assert type(init_state) == paddle.Tensor or type(init_state) == np.ndarray, \
invisible_points = np.array([[0.03440399, 0.30279721, 0.95243384], 'the type of input data should be "paddle.Tensor" or "numpy.ndarray".'
[0.70776026, 0.57712403, 0.40743499], assert type(rotating_angle) == tuple or type(rotating_angle) == list, \
[0.46991358, -0.63717908, 0.61088792]]) 'the type of rotating_angle should be "tuple" or "list".'
ax.scatter( assert len(rotating_angle) == 3, \
invisible_points[:, 0], invisible_points[:, 1], invisible_points[:, 2], 'the rotating_angle must include [theta=paddle.Tensor, phi=paddle.Tensor, lam=paddle.Tensor].'
c='w', alpha=0.01 for i in range(3):
) assert type(rotating_angle[i]) == paddle.Tensor or type(rotating_angle[i]) == float, \
'the rotating_angle must include [theta=paddle.Tensor, phi=paddle.Tensor, lam=paddle.Tensor].'
if color_scheme is not None:
assert type(color_scheme) == list and len(color_scheme) <= 3, \
'the type of "color_scheme" should be "list" and ' \
'the length of "color_scheme" should be less than or equal to "3".'
for i in range(len(color_scheme)):
assert type(color_scheme[i]) == str, \
'the type of "color_scheme[i] should be "str".'
# clean plt # Assign a value to an empty variable
if clear_plt: if filename is None:
ax.cla() filename = 'rotation_in_bloch_sphere.gif'
draw_general_frame()
# Draw the data points # Assign colors to bloch vectors
if bloch_vectors is not None: color_list = ['orangered', 'lightsalmon', 'darkred']
ax.scatter( if color_scheme is not None:
bloch_vectors[:, 0], bloch_vectors[:, 1], bloch_vectors[:, 2], c=color, alpha=1.0 for i in range(len(color_scheme)):
) color_list[i] = color_scheme[i]
set_init_color, set_trac_color, set_end_color = color_list
# if show the rotating angle theta, phi, lam = rotating_angle
if rotating_angle_list is not None:
bloch_num = len(bloch_vectors)
rotating_angle_theta, rotating_angle_phi, rotating_angle_lam = rotating_angle_list[bloch_num - 1]
rotating_angle_theta = round(rotating_angle_theta, 6)
rotating_angle_phi = round(rotating_angle_phi, 6)
rotating_angle_lam = round(rotating_angle_lam, 6)
# Shown at the top right of the perspective # Convert Tensor to numpy
display_text_angle = [-(view_angle[0] - 10), (view_angle[1] + 10)] if type(init_state) == paddle.Tensor:
text_point_x = 2 * np.cos(display_text_angle[0]) * np.cos(display_text_angle[1]) init_state = init_state.numpy()
text_point_y = 2 * np.cos(display_text_angle[0]) * np.sin(-display_text_angle[1])
text_point_z = 2 * np.sin(-display_text_angle[0])
ax.text(text_point_x, text_point_y, text_point_z, r'$\theta=' + str(rotating_angle_theta) + r'$',
color="black", fontsize=14)
ax.text(text_point_x, text_point_y, text_point_z - 0.1, r'$\phi=' + str(rotating_angle_phi) + r'$',
color="black", fontsize=14)
ax.text(text_point_x, text_point_y, text_point_z - 0.2, r'$\lambda=' + str(rotating_angle_lam) + r'$',
color="black", fontsize=14)
# If show the bloch_vector # Convert state_vector to density_matrix
if show_arrow: if init_state.size == 2:
ax.quiver( state_vector = init_state
0, 0, 0, bloch_vectors[:, 0], bloch_vectors[:, 1], bloch_vectors[:, 2], init_state = np.outer(state_vector, np.conj(state_vector))
arrow_length_ratio=0.05, color=color, alpha=1.0
)
def plot_n_qubit_state_in_bloch_sphere( # Rotating angle
state, def rotating_operation(rotating_angle_each):
which_qubits=None, gate_matrix = simulator.u_gate_matrix(rotating_angle_each)
show_arrow=False, return np.matmul(np.matmul(gate_matrix, init_state), gate_matrix.conj().T)
save_gif=False,
save_pic=True, # Rotating angle division
filename=None, rotating_frame = 50
view_angle=None, rotating_angle_list = []
view_dist=None, state = []
set_color='#0000FF' for i in range(rotating_frame + 1):
): angle_each = [theta / rotating_frame * i, phi / rotating_frame * i, lam / rotating_frame * i]
r"""将输入的多量子比特的量子态展示在 Bloch 球面上 rotating_angle_list.append(angle_each)
state.append(rotating_operation(angle_each))
state_len = len(state)
# Calc the bloch_vectors
bloch_vector_list = []
for i in range(state_len):
bloch_vector_tmp = __density_matrix_convert_to_bloch_vector(state[i])
bloch_vector_list.append(bloch_vector_tmp)
# List must be converted to array for slicing.
bloch_vectors = np.array(bloch_vector_list)
# A update function for animation class
def update(frame):
frame = frame + 2
if frame <= len(bloch_vectors) - 1:
__plot_bloch_sphere(
ax, bloch_vectors[1:frame], show_arrow=show_arrow, clear_plt=True,
rotating_angle_list=rotating_angle_list,
view_angle=view_angle, view_dist=view_dist, set_color=set_trac_color
)
# The starting and ending bloch vector has to be shown
# show starting vector
__plot_bloch_sphere(
ax, bloch_vectors[:1], show_arrow=True, clear_plt=False,
view_angle=view_angle, view_dist=view_dist, set_color=set_init_color
)
# Show ending vector
if frame == len(bloch_vectors):
__plot_bloch_sphere(
ax, bloch_vectors[frame - 1:frame], show_arrow=True, clear_plt=False,
view_angle=view_angle, view_dist=view_dist, set_color=set_end_color
)
if save_gif:
# Helper function to plot vectors on a sphere.
fig = plt.figure(figsize=(8, 8), dpi=100)
fig.subplots_adjust(left=0, right=1, bottom=0, top=1)
ax = fig.add_subplot(111, projection='3d')
# Dynamic update and save
stop_frames = 15
frames_num = len(bloch_vectors) - 2 + stop_frames
anim = animation.FuncAnimation(fig, update, frames=frames_num, interval=100, repeat=False)
anim.save(filename, dpi=100, writer='pillow')
# close the plt
plt.close(fig)
# Helper function to plot vectors on a sphere.
fig = plt.figure(figsize=(8, 8), dpi=100)
fig.subplots_adjust(left=0, right=1, bottom=0, top=1)
ax = fig.add_subplot(111, projection='3d')
# Draw the penultimate bloch vector
update(len(bloch_vectors) - 3)
# Draw the last bloch vector
update(len(bloch_vectors) - 2)
plt.show()
def plot_density_matrix_graph(density_matrix, size=0.3):
r"""密度矩阵可视化工具。
Args:
density_matrix (numpy.ndarray or paddle.Tensor): 多量子比特的量子态的状态向量或者密度矩阵,要求量子数大于 1
size (float): 条宽度,在 0 到 1 之间,默认为 0.3
"""
if not isinstance(density_matrix, (np.ndarray, paddle.Tensor)):
msg = f'Expected density_matrix to be np.ndarray or paddle.Tensor, but got {type(density_matrix)}'
raise TypeError(msg)
if isinstance(density_matrix, paddle.Tensor):
density_matrix = density_matrix.numpy()
if density_matrix.shape[0] != density_matrix.shape[1]:
msg = f'Expected density matrix dim0 equal to dim1, but got dim0={density_matrix.shape[0]}, dim1={density_matrix.shape[1]}'
raise ValueError(msg)
real = density_matrix.real
imag = density_matrix.imag
figure = plt.figure()
ax_real = figure.add_subplot(121, projection='3d', title="real")
ax_imag = figure.add_subplot(122, projection='3d', title="imag")
xx, yy = np.meshgrid(
list(range(real.shape[0])), list(range(real.shape[1])))
xx, yy = xx.ravel(), yy.ravel()
real = real.reshape(-1)
imag = imag.reshape(-1)
ax_real.bar3d(xx, yy, np.zeros_like(real), size, size, np.abs(real))
ax_imag.bar3d(xx, yy, np.zeros_like(imag), size, size, np.abs(imag))
plt.show()
return
def image_to_density_matrix(image_filepath):
r"""将图片编码为密度矩阵
Args:
image_filepath (str): 图片文件的路径
Return:
rho (numpy.ndarray): 编码得到的密度矩阵
"""
image_matrix = matplotlib.image.imread(image_filepath)
# Converting images to grayscale
image_matrix = image_matrix.mean(axis=2)
# Fill the matrix so that it becomes a matrix whose shape is [2**n,2**n]
length = int(2**np.ceil(np.log2(np.max(image_matrix.shape))))
image_matrix = np.pad(image_matrix, ((0, length-image_matrix.shape[0]), (0, length-image_matrix.shape[1])), 'constant')
# Density matrix whose trace is 1
rho = image_matrix@image_matrix.T
rho = rho/np.trace(rho)
return rho
def pauli_basis(n):
r"""生成 n 量子比特的泡利基空间
Args:
n (int): 量子比特的数量
Return:
tuple:
- basis_str: 泡利基空间的一组基底表示(array形式)
- label_str: 泡利基空间对应的一组基底表示(标签形式),形如``[ 'X', 'Y', 'Z', 'I']``
"""
sigma_x = np.array([[0, 1], [1, 0]], dtype=np.complex128)
sigma_y = np.array([[0, -1j], [1j, 0]], dtype=np.complex128)
sigma_z = np.array([[1, 0], [0, -1]], dtype=np.complex128)
sigma_id = np.array([[1, 0], [0, 1]], dtype=np.complex128)
pauli = [sigma_x, sigma_y, sigma_z, sigma_id]
labels = ['X', 'Y', 'Z', 'I']
num_qubits = n
num = 1
if num_qubits > 0:
basis_str = pauli[:]
label_str = labels[:]
pauli_basis = pauli[:]
pauli_label = labels[:]
while num < num_qubits:
length = len(basis_str)
for i in range(4):
for j in range(length):
basis_str.append(np.kron(basis_str[j], pauli_basis[i]))
label_str.append(label_str[j] + pauli_label[i])
basis_str = basis_str[-1:-4**(num+1)-1:-1]
label_str = label_str[-1:-4**(num+1)-1:-1]
num += 1
return basis_str, label_str
def decompose(matrix):
r"""生成 n 量子比特的泡利基空间
Args:
matrix (numpy.ndarray): 要分解的矩阵
Return:
pauli_form (list): 返回矩阵分解后的哈密顿量,形如 ``[[1, 'Z0, Z1'], [2, 'I']]``
"""
if np.log2(len(matrix)) % 1 != 0:
print("Please input correct matrix!")
return -1
basis_space, label_str = pauli_basis(np.log2(len(matrix)))
coefficients = [] # 对应的系数
pauli_word = [] # 对应的label
pauli_form = [] # 输出pauli_str list形式:[[1, 'Z0, Z1'], [2, 'I']]
for i in range(len(basis_space)):
# 求系数
a_ij = 1/len(matrix) * np.trace(matrix@basis_space[i])
if a_ij != 0:
if a_ij.imag != 0:
coefficients.append(a_ij)
else:
coefficients.append(a_ij.real)
pauli_word.append(label_str[i])
for i in range(len(coefficients)):
pauli_site = [] # 临时存放一个基
pauli_site.append(coefficients[i])
word = ''
for j in range(len(pauli_word[0])):
if pauli_word[i] == 'I'*int(np.log2(len(matrix))):
word = 'I' # 和Hamiltonian类似,若全是I就用一个I指代
break
if pauli_word[i][j] == 'I':
continue # 如果是I就不加数字下标
if j != 0 and len(word) != 0:
word += ','
word += pauli_word[i][j]
word += str(j) # 对每一个label加标签,说明是作用在哪个比特
pauli_site.append(word) # 添加上对应作用的门
pauli_form.append(pauli_site)
return pauli_form
class Hamiltonian:
r""" Paddle Quantum 中的 Hamiltonian ``class``。
用户可以通过一个 Pauli string 来实例化该 ``class``。
"""
def __init__(self, pauli_str, compress=True):
r""" 创建一个 Hamiltonian 类。
Args:
pauli_str (list): 用列表定义的 Hamiltonian,如 ``[(1, 'Z0, Z1'), (2, 'I')]``
compress (bool): 是否对输入的 list 进行自动合并(例如 ``(1, 'Z0, Z1')`` 和 ``(2, 'Z1, Z0')`` 这两项将被自动合并),默认为 ``True``
Note:
如果设置 ``compress=False``,则不会对输入的合法性进行检验。
"""
self.__coefficients = None
self.__terms = None
self.__pauli_words_r = []
self.__pauli_words = []
self.__sites = []
self.__nqubits = None
# when internally updating the __pauli_str, be sure to set __update_flag to True
self.__pauli_str = pauli_str
self.__update_flag = True
self.__decompose()
if compress:
self.__compress()
def __getitem__(self, indices):
new_pauli_str = []
if isinstance(indices, int):
indices = [indices]
elif isinstance(indices, slice):
indices = list(range(self.n_terms)[indices])
elif isinstance(indices, tuple):
indices = list(indices)
for index in indices:
new_pauli_str.append([self.coefficients[index], ','.join(self.terms[index])])
return Hamiltonian(new_pauli_str, compress=False)
def __add__(self, h_2):
new_pauli_str = self.pauli_str.copy()
if isinstance(h_2, float) or isinstance(h_2, int):
new_pauli_str.extend([[float(h_2), 'I']])
else:
new_pauli_str.extend(h_2.pauli_str)
return Hamiltonian(new_pauli_str)
def __mul__(self, other):
new_pauli_str = copy.deepcopy(self.pauli_str)
for i in range(len(new_pauli_str)):
new_pauli_str[i][0] *= other
return Hamiltonian(new_pauli_str, compress=False)
def __sub__(self, other):
return self.__add__(other.__mul__(-1))
def __str__(self):
str_out = ''
for idx in range(self.n_terms):
str_out += '{} '.format(self.coefficients[idx])
for _ in range(len(self.terms[idx])):
str_out += self.terms[idx][_]
if _ != len(self.terms[idx]) - 1:
str_out += ', '
if idx != self.n_terms - 1:
str_out += '\n'
return str_out
def __repr__(self):
return 'paddle_quantum.Hamiltonian object: \n' + self.__str__()
@property
def n_terms(self):
r"""返回该哈密顿量的项数
Returns:
int :哈密顿量的项数
"""
return len(self.__pauli_str)
@property
def pauli_str(self):
r"""返回哈密顿量对应的 Pauli string
Returns:
list : 哈密顿量对应的 Pauli string
"""
return self.__pauli_str
@property
def terms(self):
r"""返回哈密顿量中的每一项构成的列表
Returns:
list :哈密顿量中的每一项,i.e. ``[['Z0, Z1'], ['I']]``
"""
if self.__update_flag:
self.__decompose()
return self.__terms
else:
return self.__terms
@property
def coefficients(self):
r""" 返回哈密顿量中的每一项对应的系数构成的列表
Returns:
list :哈密顿量中每一项的系数,i.e. ``[1.0, 2.0]``
"""
if self.__update_flag:
self.__decompose()
return self.__coefficients
else:
return self.__coefficients
@property
def pauli_words(self):
r"""返回哈密顿量中每一项对应的 Pauli word 构成的列表
Returns:
list :每一项对应的 Pauli word,i.e. ``['ZIZ', 'IIX']``
"""
if self.__update_flag:
self.__decompose()
return self.__pauli_words
else:
return self.__pauli_words
@property
def pauli_words_r(self):
r"""返回哈密顿量中每一项对应的简化(不包含 I) Pauli word 组成的列表
Returns:
list :不包含 "I" 的 Pauli word 构成的列表,i.e. ``['ZXZZ', 'Z', 'X']``
"""
if self.__update_flag:
self.__decompose()
return self.__pauli_words_r
else:
return self.__pauli_words_r
@property
def sites(self):
r"""返回该哈密顿量中的每一项对应的量子比特编号组成的列表
Returns:
list :哈密顿量中每一项所对应的量子比特编号构成的列表,i.e. ``[[1, 2], [0]]``
"""
if self.__update_flag:
self.__decompose()
return self.__sites
else:
return self.__sites
@property
def n_qubits(self):
r"""返回该哈密顿量对应的量子比特数
Returns:
int :量子比特数
"""
if self.__update_flag:
self.__decompose()
return self.__nqubits
else:
return self.__nqubits
def __decompose(self):
r"""将哈密顿量分解为不同的形式
Notes:
这是一个内部函数,你不需要直接使用它
这是一个比较基础的函数,它负责将输入的 Pauli string 拆分为不同的形式并存储在内部变量中
"""
self.__pauli_words = []
self.__pauli_words_r = []
self.__sites = []
self.__terms = []
self.__coefficients = []
self.__nqubits = 1
new_pauli_str = []
for coefficient, pauli_term in self.__pauli_str:
pauli_word_r = ''
site = []
single_pauli_terms = re.split(r',\s*', pauli_term.upper())
self.__coefficients.append(float(coefficient))
self.__terms.append(single_pauli_terms)
for single_pauli_term in single_pauli_terms:
match_I = re.match(r'I', single_pauli_term, flags=re.I)
if match_I:
assert single_pauli_term[0].upper() == 'I', \
'The offset is defined with a sole letter "I", i.e. (3.0, "I")'
pauli_word_r += 'I'
site.append('')
else:
match = re.match(r'([XYZ])([0-9]+)', single_pauli_term, flags=re.I)
if match:
pauli_word_r += match.group(1).upper()
assert int(match.group(2)) not in site, 'each Pauli operator should act on different qubit'
site.append(int(match.group(2)))
else:
raise Exception(
'Operators should be defined with a string composed of Pauli operators followed' +
'by qubit index on which it act, separated with ",". i.e. "Z0, X1"')
self.__nqubits = max(self.__nqubits, int(match.group(2)) + 1)
self.__pauli_words_r.append(pauli_word_r)
self.__sites.append(site)
new_pauli_str.append([float(coefficient), pauli_term.upper()])
for term_index in range(len(self.__pauli_str)):
pauli_word = ['I' for _ in range(self.__nqubits)]
site = self.__sites[term_index]
for site_index in range(len(site)):
if type(site[site_index]) == int:
pauli_word[site[site_index]] = self.__pauli_words_r[term_index][site_index]
self.__pauli_words.append(''.join(pauli_word))
self.__pauli_str = new_pauli_str
self.__update_flag = False
def __compress(self):
r""" 对同类项进行合并。
Notes:
这是一个内部函数,你不需要直接使用它
"""
if self.__update_flag:
self.__decompose()
else:
pass
new_pauli_str = []
flag_merged = [False for _ in range(self.n_terms)]
for term_idx_1 in range(self.n_terms):
if not flag_merged[term_idx_1]:
for term_idx_2 in range(term_idx_1 + 1, self.n_terms):
if not flag_merged[term_idx_2]:
if self.pauli_words[term_idx_1] == self.pauli_words[term_idx_2]:
self.__coefficients[term_idx_1] += self.__coefficients[term_idx_2]
flag_merged[term_idx_2] = True
else:
pass
if self.__coefficients[term_idx_1] != 0:
new_pauli_str.append([self.__coefficients[term_idx_1], ','.join(self.__terms[term_idx_1])])
self.__pauli_str = new_pauli_str
self.__update_flag = True
def decompose_with_sites(self):
r"""将 pauli_str 分解为系数、泡利字符串的简化形式以及它们分别作用的量子比特下标。
Returns:
tuple: 包含如下元素的 tuple:
- coefficients (list): 元素为每一项的系数
- pauli_words_r (list): 元素为每一项的泡利字符串的简化形式,例如 'Z0, Z1, X3' 这一项的泡利字符串为 'ZZX'
- sites (list): 元素为每一项作用的量子比特下标,例如 'Z0, Z1, X3' 这一项的 site 为 [0, 1, 3]
"""
if self.__update_flag:
self.__decompose()
return self.coefficients, self.__pauli_words_r, self.__sites
def decompose_pauli_words(self):
r"""将 pauli_str 分解为系数和泡利字符串。
Returns:
tuple: 包含如下元素的 tuple:
- coefficients(list): 元素为每一项的系数
- pauli_words(list): 元素为每一项的泡利字符串,例如 'Z0, Z1, X3' 这一项的泡利字符串为 'ZZIX'
"""
if self.__update_flag:
self.__decompose()
else:
pass
return self.coefficients, self.__pauli_words
def construct_h_matrix(self, qubit_num=None):
r"""构建 Hamiltonian 在 Z 基底下的矩阵。
Returns:
np.ndarray: Z 基底下的哈密顿量矩阵形式
"""
coefs, pauli_words, sites = self.decompose_with_sites()
if qubit_num is None:
qubit_num = 1
for site in sites:
if type(site[0]) is int:
qubit_num = max(qubit_num, max(site) + 1)
else:
assert qubit_num >= self.n_qubits, "输入的量子数不小于哈密顿量表达式中所对应的量子比特数"
n_qubit = qubit_num
h_matrix = np.zeros([2 ** n_qubit, 2 ** n_qubit], dtype='complex64')
spin_ops = SpinOps(n_qubit, use_sparse=True)
for idx in range(len(coefs)):
op = coefs[idx] * sparse.eye(2 ** n_qubit, dtype='complex64')
for site_idx in range(len(sites[idx])):
if re.match(r'X', pauli_words[idx][site_idx], re.I):
op = op.dot(spin_ops.sigx_p[sites[idx][site_idx]])
elif re.match(r'Y', pauli_words[idx][site_idx], re.I):
op = op.dot(spin_ops.sigy_p[sites[idx][site_idx]])
elif re.match(r'Z', pauli_words[idx][site_idx], re.I):
op = op.dot(spin_ops.sigz_p[sites[idx][site_idx]])
h_matrix += op
return h_matrix
class SpinOps:
r"""矩阵表示下的自旋算符,可以用来构建哈密顿量矩阵或者自旋可观测量。
Args:
state (numpy.ndarray or paddle.Tensor): 输入的量子态,可以支持态矢量和密度矩阵,
该函数下,列表内每一个量子态对应一张单独的图片
which_qubits(list or None):若为多量子比特,则给出要展示的量子比特,默认为 None,表示全展示
show_arrow (bool): 是否展示向量的箭头,默认为 ``False``
save_gif (bool): 是否存储 gif 动图,默认为 ``False``
save_pic (bool): 是否存储静态图片,默认为 ``True``
filename (str): 存储的 gif 动图的名字
view_angle (list or tuple): 视图的角度,
第一个元素为关于 xy 平面的夹角 [0-360],第二个元素为关于 xz 平面的夹角 [0-360], 默认为 ``(30, 45)``
view_dist (int): 视图的距离,默认为 7
set_color (str): 若要设置指定的颜色,请查阅 ``cmap`` 表。默认为蓝色
""" """
# Check input data def __init__(self, size: int, use_sparse=False):
__input_args_dtype_check(show_arrow, save_gif, filename, view_angle, view_dist) r"""SpinOps 的构造函数,用于实例化一个 SpinOps 对象。
assert type(state) == paddle.Tensor or type(state) == np.ndarray, \
'the type of "state" must be "paddle.Tensor" or "np.ndarray".'
assert type(set_color) == str, \
'the type of "set_color" should be "str".'
n_qubits = int(np.log2(state.shape[0]))
if which_qubits is None: Args:
which_qubits = list(range(n_qubits)) size (int): 系统的大小(有几个量子比特)
else: use_sparse (bool): 是否使用 sparse matrix 计算,默认为 ``False``
assert type(which_qubits)==list,'the type of which_qubits should be None or list' """
assert 1<=len(which_qubits)<=n_qubits,'展示的量子数量需要小于n_qubits' self.size = size
for i in range(len(which_qubits)): self.id = sparse.eye(2, dtype='complex128')
assert 0<=which_qubits[i]<n_qubits, '0<which_qubits[i]<n_qubits' self.__sigz = sparse.bsr.bsr_matrix([[1, 0], [0, -1]], dtype='complex64')
self.__sigy = sparse.bsr.bsr_matrix([[0, -1j], [1j, 0]], dtype='complex64')
# Assign a value to an empty variable self.__sigx = sparse.bsr.bsr_matrix([[0, 1], [1, 0]], dtype='complex64')
if filename is None: self.__sigz_p = []
filename = 'state_in_bloch_sphere.gif' self.__sigy_p = []
if view_angle is None: self.__sigx_p = []
view_angle = (30, 45) self.__sparse = use_sparse
if view_dist is None: for i in range(self.size):
view_dist = 7 self.__sigz_p.append(self.__direct_prod_op(spin_op=self.__sigz, spin_index=i))
self.__sigy_p.append(self.__direct_prod_op(spin_op=self.__sigy, spin_index=i))
self.__sigx_p.append(self.__direct_prod_op(spin_op=self.__sigx, spin_index=i))
# Convert Tensor to numpy @property
if type(state) == paddle.Tensor: def sigz_p(self):
state = state.numpy() r""" :math:`Z` 基底下的 :math:`S^z_i` 算符。
#state_vector to density matrix Returns:
if state.shape[0]>=2 and state.size==state.shape[0]: list : :math:`S^z_i` 算符组成的列表,其中每一项对应不同的 :math:`i`
state_vector = state """
state = np.outer(state_vector, np.conj(state_vector)) return self.__sigz_p
#多量子态分解
if state.shape[0]>2:
rho = paddle.to_tensor(state)
tmp_s = []
for q in which_qubits:
tmp_s.append(partial_trace_discontiguous(rho,[q]))
state = tmp_s
else:
state = [state]
state_len = len(state)
# Calc the bloch_vectors
bloch_vector_list = []
for i in range(state_len):
bloch_vector_tmp = __density_matrix_convert_to_bloch_vector(state[i])
bloch_vector_list.append(bloch_vector_tmp)
# List must be converted to array for slicing. @property
bloch_vectors = np.array(bloch_vector_list) def sigy_p(self):
r""" :math:`Z` 基底下的 :math:`S^y_i` 算符。
# A update function for animation class Returns:
def update(frame): list : :math:`S^y_i` 算符组成的列表,其中每一项对应不同的 :math:`i`
view_rotating_angle = 5 """
new_view_angle = [view_angle[0], view_angle[1] + view_rotating_angle * frame] return self.__sigy_p
__plot_bloch_sphere(
ax, bloch_vectors, show_arrow, clear_plt=True,
view_angle=new_view_angle, view_dist=view_dist, set_color=set_color
)
# Dynamic update and save @property
if save_gif: def sigx_p(self):
# Helper function to plot vectors on a sphere. r""" :math:`Z` 基底下的 :math:`S^x_i` 算符。
fig = plt.figure(figsize=(8, 8), dpi=100)
fig.subplots_adjust(left=0, right=1, bottom=0, top=1)
ax = fig.add_subplot(111, projection='3d')
frames_num = 7 Returns:
anim = animation.FuncAnimation(fig, update, frames=frames_num, interval=600, repeat=False) list : :math:`S^x_i` 算符组成的列表,其中每一项对应不同的 :math:`i`
anim.save(filename, dpi=100, writer='pillow') """
# close the plt return self.__sigx_p
plt.close(fig)
# Helper function to plot vectors on a sphere. def __direct_prod_op(self, spin_op, spin_index):
fig = plt.figure(figsize=(8, 8), dpi=100) r"""直积,得到第 n 个自旋(量子比特)上的自旋算符
fig.subplots_adjust(left=0, right=1, bottom=0, top=1)
dim = np.ceil(sqrt(len(which_qubits)))
for i in range(1,len(which_qubits)+1):
ax = fig.add_subplot(dim,dim,i,projection='3d')
bloch_vector=np.array([bloch_vectors[i-1]])
__plot_bloch_sphere(
ax, bloch_vector, show_arrow, clear_plt=True,
view_angle=view_angle, view_dist=view_dist, set_color=set_color
)
if save_pic:
plt.savefig('n_qubit_state_in_bloch.png',bbox_inches='tight')
plt.show()
def plot_state_in_bloch_sphere( Args:
state, spin_op: 单体自旋算符
show_arrow=False, spin_index: 标记第 n 个自旋(量子比特)
save_gif=False,
filename=None, Returns:
view_angle=None, scipy.sparse or np.ndarray: 直积后的自旋算符,其数据类型取决于 self.__use_sparse
view_dist=None, """
set_color=None s_p = copy.copy(spin_op)
for i in range(self.size):
if i < spin_index:
s_p = sparse.kron(self.id, s_p)
elif i > spin_index:
s_p = sparse.kron(s_p, self.id)
if self.__sparse:
return s_p
else:
return s_p.toarray()
def __input_args_dtype_check(
show_arrow,
save_gif,
filename,
view_angle,
view_dist
): ):
r"""将输入的量子态展示在 Bloch 球面上 r"""
该函数实现对输入默认参数的数据类型检查,保证输入函数中的参数为所允许的数据类型
Args: Args:
state (list(numpy.ndarray or paddle.Tensor)): 输入的量子态列表,可以支持态矢量和密度矩阵 show_arrow (bool): 是否展示向量的箭头,默认为 False
show_arrow (bool): 是否展示向量的箭头,默认为 ``False`` save_gif (bool): 是否存储 gif 动图
save_gif (bool): 是否存储 gif 动图,默认为 ``False``
filename (str): 存储的 gif 动图的名字 filename (str): 存储的 gif 动图的名字
view_angle (list or tuple): 视图的角度, view_angle (list or tuple): 视图的角度,
第一个元素为关于 xy 平面的夹角 [0-360],第二个元素为关于 xz 平面的夹角 [0-360], 默认为 ``(30, 45)`` 第一个元素为关于xy平面的夹角[0-360],第二个元素为关于xz平面的夹角[0-360], 默认为 (30, 45)
view_dist (int): 视图的距离,默认为 7 view_dist (int): 视图的距离,默认为 7
set_color (str): 若要设置指定的颜色,请查阅 ``cmap`` 表。默认为红色到黑色的渐变颜色
""" """
# Check input data
__input_args_dtype_check(show_arrow, save_gif, filename, view_angle, view_dist)
assert type(state) == list or type(state) == paddle.Tensor or type(state) == np.ndarray, \
'the type of "state" must be "list" or "paddle.Tensor" or "np.ndarray".'
if type(state) == paddle.Tensor or type(state) == np.ndarray:
state = [state]
state_len = len(state)
assert state_len >= 1, '"state" is NULL.'
for i in range(state_len):
assert type(state[i]) == paddle.Tensor or type(state[i]) == np.ndarray, \
'the type of "state[i]" should be "paddle.Tensor" or "numpy.ndarray".'
if set_color is not None:
assert type(set_color) == str, \
'the type of "set_color" should be "str".'
# Assign a value to an empty variable
if filename is None:
filename = 'state_in_bloch_sphere.gif'
if view_angle is None:
view_angle = (30, 45)
if view_dist is None:
view_dist = 7
# Convert Tensor to numpy if show_arrow is not None:
for i in range(state_len): assert type(show_arrow) == bool, \
if type(state[i]) == paddle.Tensor: 'the type of "show_arrow" should be "bool".'
state[i] = state[i].numpy() if save_gif is not None:
assert type(save_gif) == bool, \
# Convert state_vector to density_matrix 'the type of "save_gif" should be "bool".'
for i in range(state_len): if save_gif:
if state[i].size == 2: if filename is not None:
state_vector = state[i] assert type(filename) == str, \
state[i] = np.outer(state_vector, np.conj(state_vector)) 'the type of "filename" should be "str".'
other, ext = os.path.splitext(filename)
assert ext == '.gif', 'The suffix of the file name must be "gif".'
# If it does not exist, create a folder
path, file = os.path.split(filename)
if not os.path.exists(path):
os.makedirs(path)
if view_angle is not None:
assert type(view_angle) == list or type(view_angle) == tuple, \
'the type of "view_angle" should be "list" or "tuple".'
for i in range(2):
assert type(view_angle[i]) == int, \
'the type of "view_angle[0]" and "view_angle[1]" should be "int".'
if view_dist is not None:
assert type(view_dist) == int, \
'the type of "view_dist" should be "int".'
# Calc the bloch_vectors
bloch_vector_list = []
for i in range(state_len):
bloch_vector_tmp = __density_matrix_convert_to_bloch_vector(state[i])
bloch_vector_list.append(bloch_vector_tmp)
# List must be converted to array for slicing. class QuantumFisher:
bloch_vectors = np.array(bloch_vector_list) r"""量子费舍信息及相关量的计算器。
# A update function for animation class Attributes:
def update(frame): cir (UAnsatz): 需要计算量子费舍信息的参数化量子电路
view_rotating_angle = 5 """
new_view_angle = [view_angle[0], view_angle[1] + view_rotating_angle * frame] def __init__(self, cir):
__plot_bloch_sphere( r"""QuantumFisher 的构造函数,用于实例化一个量子费舍信息的计算器。
ax, bloch_vectors, show_arrow, clear_plt=True,
view_angle=new_view_angle, view_dist=view_dist, set_color=set_color
)
# Dynamic update and save Args:
if save_gif: cir (UAnsatz): 需要计算量子费舍信息的参数化量子电路
# Helper function to plot vectors on a sphere. """
fig = plt.figure(figsize=(8, 8), dpi=100) self.cir = cir
fig.subplots_adjust(left=0, right=1, bottom=0, top=1)
ax = fig.add_subplot(111, projection='3d')
frames_num = 7 def get_qfisher_matrix(self):
anim = animation.FuncAnimation(fig, update, frames=frames_num, interval=600, repeat=False) r"""利用二阶参数平移规则计算量子费舍信息矩阵。
anim.save(filename, dpi=100, writer='pillow')
# close the plt
plt.close(fig)
# Helper function to plot vectors on a sphere. Returns:
fig = plt.figure(figsize=(8, 8), dpi=100) numpy.ndarray: 量子费舍信息矩阵
fig.subplots_adjust(left=0, right=1, bottom=0, top=1)
ax = fig.add_subplot(111, projection='3d') 代码示例:
__plot_bloch_sphere(
ax, bloch_vectors, show_arrow, clear_plt=True,
view_angle=view_angle, view_dist=view_dist, set_color=set_color
)
plt.show() .. code-block:: python
import paddle
from paddle_quantum.circuit import UAnsatz
from paddle_quantum.utils import QuantumFisher
def plot_rotation_in_bloch_sphere( cir = UAnsatz(1)
init_state, cir.ry(theta=paddle.to_tensor(0., dtype="float64", stop_gradient=False),
rotating_angle, which_qubit=0)
show_arrow=False, cir.rz(theta=paddle.to_tensor(0., dtype="float64", stop_gradient=False),
save_gif=False, which_qubit=0)
filename=None,
view_angle=None,
view_dist=None,
color_scheme=None,
):
r"""在 Bloch 球面上刻画从初始量子态开始的旋转轨迹
Args: qf = QuantumFisher(cir)
init_state (numpy.ndarray or paddle.Tensor): 输入的初始量子态,可以支持态矢量和密度矩阵 qfim = qf.get_qfisher_matrix()
rotating_angle (list(float)): 旋转角度 ``[theta, phi, lam]`` print(f'The QFIM at {cir.get_param().tolist()} is \n {qfim}.')
show_arrow (bool): 是否展示向量的箭头,默认为 ``False``
save_gif (bool): 是否存储 gif 动图,默认为 ``False``
filename (str): 存储的 gif 动图的名字
view_angle (list or tuple): 视图的角度,
第一个元素为关于 xy 平面的夹角 [0-360],第二个元素为关于 xz 平面的夹角 [0-360], 默认为 ``(30, 45)``
view_dist (int): 视图的距离,默认为 7
color_scheme (list(str,str,str)): 分别是初始颜色,轨迹颜色,结束颜色。若要设置指定的颜色,请查阅 ``cmap`` 表。默认为红色
"""
# Check input data
__input_args_dtype_check(show_arrow, save_gif, filename, view_angle, view_dist)
assert type(init_state) == paddle.Tensor or type(init_state) == np.ndarray, \ ::
'the type of input data should be "paddle.Tensor" or "numpy.ndarray".'
assert type(rotating_angle) == tuple or type(rotating_angle) == list, \
'the type of rotating_angle should be "tuple" or "list".'
assert len(rotating_angle) == 3, \
'the rotating_angle must include [theta=paddle.Tensor, phi=paddle.Tensor, lam=paddle.Tensor].'
for i in range(3):
assert type(rotating_angle[i]) == paddle.Tensor or type(rotating_angle[i]) == float, \
'the rotating_angle must include [theta=paddle.Tensor, phi=paddle.Tensor, lam=paddle.Tensor].'
if color_scheme is not None:
assert type(color_scheme) == list and len(color_scheme) <= 3, \
'the type of "color_scheme" should be "list" and ' \
'the length of "color_scheme" should be less than or equal to "3".'
for i in range(len(color_scheme)):
assert type(color_scheme[i]) == str, \
'the type of "color_scheme[i] should be "str".'
# Assign a value to an empty variable The QFIM at [0.0, 0.0] is
if filename is None: [[1. 0.]
filename = 'rotation_in_bloch_sphere.gif' [0. 0.]].
"""
# Get the real-time parameters from the UAnsatz class
list_param = self.cir.get_param().tolist()
num_param = len(list_param)
# Initialize a numpy array to record the QFIM
qfim = np.zeros((num_param, num_param))
# Assign the signs corresponding to the four terms in a QFIM element
list_sign = [[1, 1], [1, -1], [-1, 1], [-1, -1]]
# Run the circuit and record the current state vector
psi = self.cir.run_state_vector().numpy()
# For each QFIM element
for i in range(0, num_param):
for j in range(i, num_param):
# For each term in each element
for sign_i, sign_j in list_sign:
# Shift the parameters by pi/2 * sign
list_param[i] += np.pi / 2 * sign_i
list_param[j] += np.pi / 2 * sign_j
# Update the parameters in the circuit
self.cir.update_param(list_param)
# Run the shifted circuit and record the shifted state vector
psi_shift = self.cir.run_state_vector().numpy()
# Calculate each term as the fidelity with a sign factor
qfim[i][j] += abs(np.vdot(
psi_shift, psi))**2 * sign_i * sign_j * (-0.5)
# De-shift the parameters
list_param[i] -= np.pi / 2 * sign_i
list_param[j] -= np.pi / 2 * sign_j
self.cir.update_param(list_param)
if i != j:
# The QFIM is symmetric
qfim[j][i] = qfim[i][j]
return qfim
def get_qfisher_norm(self, direction, step_size=0.01):
r"""利用有限差分计算沿给定方向的量子费舍信息的投影。
# Assign colors to bloch vectors Args:
color_list = ['orangered', 'lightsalmon', 'darkred'] direction (list): 要计算量子费舍信息投影的方向
if color_scheme is not None: step_size (float, optional): 有限差分的步长,默认为 0.01
for i in range(len(color_scheme)):
color_list[i] = color_scheme[i]
set_init_color, set_trac_color, set_end_color = color_list
theta, phi, lam = rotating_angle Returns:
float: 沿给定方向的量子费舍信息的投影
# Convert Tensor to numpy 代码示例:
if type(init_state) == paddle.Tensor:
init_state = init_state.numpy()
# Convert state_vector to density_matrix .. code-block:: python
if init_state.size == 2:
state_vector = init_state
init_state = np.outer(state_vector, np.conj(state_vector))
# Rotating angle import paddle
def rotating_operation(rotating_angle_each): from paddle_quantum.circuit import UAnsatz
gate_matrix = simulator.u_gate_matrix(rotating_angle_each) from paddle_quantum.utils import QuantumFisher
return np.matmul(np.matmul(gate_matrix, init_state), gate_matrix.conj().T)
# Rotating angle division cir = UAnsatz(2)
rotating_frame = 50 cir.ry(theta=paddle.to_tensor(0., dtype="float64", stop_gradient=False),
rotating_angle_list = [] which_qubit=0)
state = [] cir.ry(theta=paddle.to_tensor(0., dtype="float64", stop_gradient=False),
for i in range(rotating_frame + 1): which_qubit=1)
angle_each = [theta / rotating_frame * i, phi / rotating_frame * i, lam / rotating_frame * i] cir.cnot(control=[0, 1])
rotating_angle_list.append(angle_each) cir.ry(theta=paddle.to_tensor(0., dtype="float64", stop_gradient=False),
state.append(rotating_operation(angle_each)) which_qubit=0)
cir.ry(theta=paddle.to_tensor(0., dtype="float64", stop_gradient=False),
which_qubit=1)
state_len = len(state) qf = QuantumFisher(cir)
# Calc the bloch_vectors v = [1,1,1,1]
bloch_vector_list = [] qfi_norm = qf.get_qfisher_norm(direction=v)
for i in range(state_len): print(f'The QFI norm along {v} at {cir.get_param().tolist()} is {qfi_norm:.7f}')
bloch_vector_tmp = __density_matrix_convert_to_bloch_vector(state[i])
bloch_vector_list.append(bloch_vector_tmp)
# List must be converted to array for slicing. ::
bloch_vectors = np.array(bloch_vector_list)
# A update function for animation class The QFI norm along [1, 1, 1, 1] at [0.0, 0.0, 0.0, 0.0] is 5.9996250
def update(frame): """
frame = frame + 2 # Get the real-time parameters
if frame <= len(bloch_vectors) - 1: list_param = self.cir.get_param().tolist()
__plot_bloch_sphere( # Run the circuit and record the current state vector
ax, bloch_vectors[1:frame], show_arrow=show_arrow, clear_plt=True, psi = self.cir.run_state_vector().numpy()
rotating_angle_list=rotating_angle_list, # Check whether the length of the input direction vector is equal to the number of the variational parameters
view_angle=view_angle, view_dist=view_dist, set_color=set_trac_color assert len(list_param) == len(
) direction
), "the length of direction vector should be equal to the number of the parameters"
# Shift the parameters by step_size * direction
array_params_shift = np.array(
list_param) + np.array(direction) * step_size
# Update the parameters in the circuit
self.cir.update_param(array_params_shift.tolist())
# Run the shifted circuit and record the shifted state vector
psi_shift = self.cir.run_state_vector().numpy()
# Calculate quantum Fisher-Rao norm along the given direction
qfisher_norm = (1 - abs(np.vdot(psi_shift, psi))**2) * 4 / step_size**2
# De-shift the parameters and update
self.cir.update_param(list_param)
return qfisher_norm
def get_eff_qdim(self, num_param_samples=4, tol=None):
r"""计算有效量子维数,即量子费舍信息矩阵的秩在整个参数空间的最大值。
# The starting and ending bloch vector has to be shown Args:
# show starting vector num_param_samples (int, optional): 用来估计有效量子维数时所用的参数样本量,默认为 4
__plot_bloch_sphere( tol (float, optional): 奇异值的最小容差,低于此容差的奇异值认为是 0,默认为 None,其含义同 ``numpy.linalg.matrix_rank()``
ax, bloch_vectors[:1], show_arrow=True, clear_plt=False,
view_angle=view_angle, view_dist=view_dist, set_color=set_init_color
)
# Show ending vector Returns:
if frame == len(bloch_vectors): int: 给定量子电路对应的有效量子维数
__plot_bloch_sphere(
ax, bloch_vectors[frame - 1:frame], show_arrow=True, clear_plt=False,
view_angle=view_angle, view_dist=view_dist, set_color=set_end_color
)
if save_gif: 代码示例:
# Helper function to plot vectors on a sphere.
fig = plt.figure(figsize=(8, 8), dpi=100)
fig.subplots_adjust(left=0, right=1, bottom=0, top=1)
ax = fig.add_subplot(111, projection='3d')
# Dynamic update and save .. code-block:: python
stop_frames = 15
frames_num = len(bloch_vectors) - 2 + stop_frames
anim = animation.FuncAnimation(fig, update, frames=frames_num, interval=100, repeat=False)
anim.save(filename, dpi=100, writer='pillow')
# close the plt
plt.close(fig)
# Helper function to plot vectors on a sphere. import paddle
fig = plt.figure(figsize=(8, 8), dpi=100) from paddle_quantum.circuit import UAnsatz
fig.subplots_adjust(left=0, right=1, bottom=0, top=1) from paddle_quantum.utils import QuantumFisher
ax = fig.add_subplot(111, projection='3d')
# Draw the penultimate bloch vector cir = UAnsatz(1)
update(len(bloch_vectors) - 3) cir.rz(theta=paddle.to_tensor(0., dtype="float64", stop_gradient=False),
# Draw the last bloch vector which_qubit=0)
update(len(bloch_vectors) - 2) cir.ry(theta=paddle.to_tensor(0., dtype="float64", stop_gradient=False),
which_qubit=0)
plt.show() qf = QuantumFisher(cir)
print(cir)
print(f'The number of parameters of -Rz-Ry- is {len(cir.get_param().tolist())}')
print(f'The effective quantum dimension -Rz-Ry- is {qf.get_eff_qdim()}')
::
def pauli_basis(n): --Rz(0.000)----Ry(0.000)--
r"""生成 n 量子比特的泡利基空间
Args:
n (int): 量子比特的数量
Return: The number of parameters of -Rz-Ry- is 2
tuple: The effective quantum dimension -Rz-Ry- is 1
basis_str: 泡利基空间的一组基底表示(array形式) """
label_str: 泡利基空间对应的一组基底表示(标签形式),形如``[ 'X', 'Y', 'Z', 'I']`` # Get the real-time parameters
""" list_param = self.cir.get_param().tolist()
sigma_x = np.array([[0, 1], [1, 0]], dtype=np.complex128) num_param = len(list_param)
sigma_y = np.array([[0, -1j], [1j, 0]], dtype=np.complex128) # Generate random parameters
sigma_z = np.array([[1, 0], [0, -1]], dtype=np.complex128) param_samples = 2 * np.pi * np.random.random(
sigma_id = np.array([[1, 0], [0, 1]], dtype=np.complex128) (num_param_samples, num_param))
pauli = [sigma_x, sigma_y, sigma_z, sigma_id] # Record the ranks
labels = ['X', 'Y', 'Z', 'I'] list_ranks = []
# Here it has been assumed that the set of points that do not maximize the rank of QFIMs, as singularities, form a null set.
# Thus one can find the maximal rank using a few samples.
for param in param_samples:
# Set the random parameters
self.cir.update_param(param.tolist())
# Calculate the ranks
list_ranks.append(self.get_qfisher_rank(tol))
# Recover the original parameters
self.cir.update_param(list_param)
return max(list_ranks)
def get_qfisher_rank(self, tol=None):
r"""计算量子费舍信息矩阵的秩。
num_qubits = n Args:
num = 1 tol (float, optional): 奇异值的最小容差,低于此容差的奇异值认为是 0,默认为 None,其含义同 ``numpy.linalg.matrix_rank()``
if num_qubits > 0:
basis_str = pauli[:]
label_str = labels[:]
pauli_basis = pauli[:]
palui_label = labels[:]
while num < num_qubits:
length = len(basis_str)
for i in range(4):
for j in range(length):
basis_str.append(np.kron(basis_str[j], pauli_basis[i]))
label_str.append(label_str[j] + palui_label[i])
basis_str = basis_str[-1:-4**(num+1)-1:-1]
label_str = label_str[-1:-4**(num+1)-1:-1]
num += 1
return basis_str, label_str
Returns:
int: 量子费舍信息矩阵的秩
"""
qfisher_rank = np.linalg.matrix_rank(self.get_qfisher_matrix(),
tol,
hermitian=True)
return qfisher_rank
def decompose(matrix):
r"""生成 n 量子比特的泡利基空间
Args:
matrix (numpy.ndarray): 要分解的矩阵
Return: class ClassicalFisher:
pauli_form (list): 返回矩阵分解后的哈密顿量,形如 ``[[1, 'Z0, Z1'], [2, 'I']]`` r"""经典费舍信息及相关量的计算器。
Attributes:
model (paddle.nn.Layer): 经典或量子神经网络模型的实例
num_thetas (int): 参数集合的数量
num_inputs (int): 输入的样本数量
""" """
if np.log2(len(matrix)) % 1 != 0: def __init__(self,
print("Please input correct matrix!") model,
return -1 num_thetas,
basis_space, label_str = pauli_basis(np.log2(len(matrix))) num_inputs,
coefficients = [] # 对应的系数 model_type='quantum',
pauli_word = [] # 对应的label **kwargs):
pauli_form = [] # 输出pauli_str list形式:[[1, 'Z0, Z1'], [2, 'I']] r"""ClassicalFisher 的构造函数,用于实例化一个经典费舍信息的计算器。
for i in range(len(basis_space)):
# 求系数 Args:
a_ij = 1/len(matrix) * np.trace(matrix@basis_space[i]) model (paddle.nn.Layer): 经典或量子神经网络模型的实例
if a_ij != 0: num_thetas (int): 参数集合的数量
if a_ij.imag != 0: num_inputs (int): 输入的样本数量
coefficients.append(a_ij) model_type (str, optional): 模型是经典 "classical" 的还是量子 "quantum" 的,默认是量子的
Note:
这里 ``**kwargs`` 包含如下选项:
- size (list): 经典神经网络各层神经元的数量
- num_qubits (int): 量子神经网络量子比特的数量
- depth (int): 量子神经网络的深度
- encoding (str): 量子神经网络中经典数据的编码方式,目前支持 "IQP" 和 "re-uploading"
Raises:
ValueError: 不被支持的编码方式
ValueError: 不被支持的模型类别
"""
self.model = model
self.num_thetas = num_thetas
self.num_inputs = num_inputs
self._model_type = model_type
if self._model_type == 'classical':
layer_dims = kwargs['size']
self.model_args = [layer_dims]
self.input_size = layer_dims[0]
self.output_size = layer_dims[-1]
self.num_params = sum(layer_dims[i] * layer_dims[i + 1]
for i in range(len(layer_dims) - 1))
elif self._model_type == 'quantum':
num_qubits = kwargs['num_qubits']
depth = kwargs['depth']
# Supported QNN encoding: ‘IQP' and 're-uploading'
encoding = kwargs['encoding']
self.model_args = [num_qubits, depth, encoding]
self.input_size = num_qubits
# Default dimension of output layer = 1
self.output_size = 1
# Determine the number of model parameters for different encoding types
if encoding == 'IQP':
self.num_params = 3 * depth * num_qubits
elif encoding == 're-uploading':
self.num_params = 3 * (depth + 1) * num_qubits
else: else:
coefficients.append(a_ij.real) raise ValueError('Non-existent encoding method')
pauli_word.append(label_str[i]) else:
for i in range(len(coefficients)): raise ValueError(
pauli_site = [] # 临时存放一个基 'The model type should be equal to either classical or quantum'
pauli_site.append(coefficients[i]) )
word = ''
for j in range(len(pauli_word[0])):
if pauli_word[i] == 'I'*int(np.log2(len(matrix))):
word = 'I' # 和Hamiltonian类似,若全是I就用一个I指代
break
if pauli_word[i][j] == 'I':
continue # 如果是I就不加数字下标
if j != 0 and len(word) != 0:
word += ','
word += pauli_word[i][j]
word += str(j) # 对每一个label加标签,说明是作用在哪个比特
pauli_site.append(word) # 添加上对应作用的门
pauli_form.append(pauli_site)
return pauli_form # Generate random data
np.random.seed(0)
x = np.random.normal(0, 1, size=(num_inputs, self.input_size))
# Use the same input data for each theta set
self.x = np.tile(x, (num_thetas, 1))
def plot_density_graph(density_matrix: Union[paddle.Tensor, np.ndarray], def get_gradient(self, x):
size: Optional[float]=.3) -> plt.Figure: r"""计算输出层关于变分参数的梯度。
r"""密度矩阵可视化工具。
Args:
density_matrix (numpy.ndarray or paddle.Tensor): 多量子比特的量子态的状态向量或者密度矩阵,要求量子数大于1
size (float): 条宽度,在0到1之间,默认0.3
Returns:
plt.Figure: 对应的密度矩阵可视化3D直方图
"""
if not isinstance(density_matrix, (np.ndarray, paddle.Tensor)):
msg = f'Expected density_matrix to be np.ndarray or paddle.Tensor, but got {type(density_matrix)}'
raise TypeError(msg)
if isinstance(density_matrix, paddle.Tensor):
density_matrix = density_matrix.numpy()
if density_matrix.shape[0] != density_matrix.shape[1]:
msg = f'Expected density matrix dim0 equal to dim1, but got dim0={density_matrix.shape[0]}, dim1={density_matrix.shape[1]}'
raise ValueError(msg)
real = density_matrix.real Args:
imag = density_matrix.imag x (numpy.ndarray): 输入样本
figure = plt.figure() Returns:
ax_real = figure.add_subplot(121, projection='3d', title="real") numpy.ndarray: 输出层关于变分参数的梯度,数组形状为(输入样本数量, 输出层维数, 变分参数数量)
ax_imag = figure.add_subplot(122, projection='3d', title="imag") """
if not paddle.is_tensor(x):
x = paddle.to_tensor(x, stop_gradient=True)
gradvectors = []
seed = 0
pbar = tqdm(desc="running in get_gradient: ",
total=len(x),
ncols=100,
ascii=True)
for m in range(len(x)):
pbar.update(1)
if m % self.num_inputs == 0:
seed += 1
paddle.seed(seed)
net = self.model(*self.model_args)
output = net(x[m])
logoutput = paddle.log(output)
grad = []
for i in range(self.output_size):
net.clear_gradients()
logoutput[i].backward(retain_graph=True)
grads = []
for param in net.parameters():
grads.append(param.grad.reshape((-1, )))
gr = paddle.concat(grads)
grad.append(gr * paddle.sqrt(output[i]))
jacobian = paddle.concat(grad)
# Jacobian matrix corresponding to each data point
jacobian = paddle.reshape(jacobian,
(self.output_size, self.num_params))
gradvectors.append(jacobian.detach().numpy())
pbar.close()
return gradvectors
def get_cfisher(self, gradients):
r"""利用雅可比矩阵计算经典费舍信息矩阵。
xx, yy = np.meshgrid( Args:
list(range(real.shape[0])), list(range(real.shape[1]))) gradients (numpy.ndarray): 输出层关于变分参数的梯度, 数组形状为(输入样本数量, 输出层维数, 变分参数数量)
xx, yy = xx.ravel(), yy.ravel()
real = real.reshape(-1)
imag = imag.reshape(-1)
ax_real.bar3d(xx, yy, np.zeros_like(real), size, size, np.abs(real)) Returns:
ax_imag.bar3d(xx, yy, np.zeros_like(imag), size, size, np.abs(imag)) numpy.ndarray: 经典费舍信息矩阵,数组形状为(输入样本数量, 变分参数数量, 变分参数数量)
"""
fishers = np.zeros((len(gradients), self.num_params, self.num_params))
for i in range(len(gradients)):
grads = gradients[i]
temp_sum = np.zeros(
(self.output_size, self.num_params, self.num_params))
for j in range(self.output_size):
temp_sum[j] += np.array(
np.outer(grads[j], np.transpose(grads[j])))
fishers[i] += np.sum(temp_sum, axis=0)
return figure return fishers
def img_to_density_matrix(img_file): def get_normalized_cfisher(self):
r"""将图片编码为密度矩阵 r"""计算归一化的经典费舍信息矩阵。
Args:
img_file: 图片文件
Return: Returns:
rho:密度矩阵 `` numpy.ndarray: 归一化的经典费舍信息矩阵,数组形状为(输入样本数量, 变分参数数量, 变分参数数量)
""" """
img_matrix = matplotlib.image.imread(img_file) grads = self.get_gradient(self.x)
fishers = self.get_cfisher(grads)
#将图片转为灰度图 fisher_trace = np.trace(np.average(fishers, axis=0))
img_matrix = img_matrix.mean(axis=2) # Average over input data
fisher = np.average(np.reshape(fishers,
#填充矩阵,使其变为[2**n,2**n]的矩阵 (self.num_thetas, self.num_inputs,
length = int(2**np.ceil(np.log2(np.max(img_matrix.shape)))) self.num_params, self.num_params)),
img_matrix = np.pad(img_matrix,((0,length-img_matrix.shape[0]),(0,length-img_matrix.shape[1])),'constant') axis=1)
#trace为1的密度矩阵 normalized_cfisher = self.num_params * fisher / fisher_trace
rho = img_matrix@img_matrix.T
rho = rho/np.trace(rho) return normalized_cfisher, fisher_trace
return rho
def get_eff_dim(self, normalized_cfisher, list_num_samples, gamma=1):
r"""计算经典的有效维数。
Args:
normalized_cfisher (numpy.ndarray): 归一化的经典费舍信息矩阵
list_num_samples (list): 不同样本量构成的列表
gamma (int, optional): 有效维数定义中包含的一个人为可调参数,默认为 1
Returns:
list: 对于不同样本量的有效维数构成的列表
"""
eff_dims = []
for n in list_num_samples:
one_plus_F = np.eye(
self.num_params) + normalized_cfisher * gamma * n / (
2 * np.pi * np.log(n))
det = np.linalg.slogdet(one_plus_F)[1]
r = det / 2
eff_dims.append(2 * (logsumexp(r) - np.log(self.num_thetas)) /
np.log(gamma * n / (2 * np.pi * np.log(n))))
return eff_dims
paddlepaddle>=2.1.1 paddlepaddle>=2.2.0
scipy scipy
networkx>=2.5 networkx>=2.5
matplotlib>=3.3.0 matplotlib>=3.3.0
interval interval
tqdm tqdm
\ No newline at end of file openfermion
pyscf; platform_system == "Linux" or platform_system == "Darwin"
...@@ -23,7 +23,7 @@ with open("README.md", "r", encoding="utf-8") as fh: ...@@ -23,7 +23,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
setuptools.setup( setuptools.setup(
name='paddle-quantum', name='paddle-quantum',
version='2.1.2', version='2.1.3',
author='Institute for Quantum Computing, Baidu INC.', author='Institute for Quantum Computing, Baidu INC.',
author_email='quantum@baidu.com', author_email='quantum@baidu.com',
description='Paddle Quantum is a quantum machine learning (QML) toolkit developed based on Baidu PaddlePaddle.', description='Paddle Quantum is a quantum machine learning (QML) toolkit developed based on Baidu PaddlePaddle.',
...@@ -48,7 +48,16 @@ setuptools.setup( ...@@ -48,7 +48,16 @@ setuptools.setup(
'paddle_quantum.mbqc.VQSVD.example': ['*.txt'], 'paddle_quantum.mbqc.VQSVD.example': ['*.txt'],
}, },
install_requires=['paddlepaddle>=2.1.2', 'scipy', 'networkx>=2.5', 'matplotlib>=3.3.0', 'interval', 'tqdm'], install_requires=[
'paddlepaddle>=2.2.0',
'scipy',
'networkx>=2.5',
'matplotlib>=3.3.0',
'interval',
'tqdm',
'openfermion',
'pyscf; platform_system == "Linux" or platform_system == "Darwin"'
],
python_requires='>=3.6, <4', python_requires='>=3.6, <4',
classifiers=[ classifiers=[
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
......
- 通过在UAnsatz类中添加新的成员函数expand来实现扩展
- 增加utils.plot_density_graph密度矩阵可视化工具。
```
Args:
density_matrix (numpy.ndarray or paddle.Tensor): 多量子比特的量子态的状态向量或者密度矩阵,要求量子数大于1
size (float): 条宽度,在0到1之间,默认0.3
Returns:
plt.Figure: 对应的密度矩阵可视化3D直方图
```
\ No newline at end of file
from paddle_quantum.circuit import UAnsatz
import matplotlib.pyplot as plt
from paddle_quantum.utils import plot_density_graph
import numpy as np
import paddle
import unittest
#density_matrix
def test_density_matrix():
cir = UAnsatz(1)
cir.ry(paddle.to_tensor(1,dtype='float64'),0)
state = cir.run_density_matrix()
cir.expand(3)
print(cir.get_state())
cir2 = UAnsatz(3)
cir2.ry(paddle.to_tensor(1,dtype='float64'),0)
cir2.run_density_matrix()
print(cir2.get_state())
#state_vector
def test_state_vector():
cir = UAnsatz(1)
cir.ry(paddle.to_tensor(1,dtype='float64'),0)
state = cir.run_state_vector()
cir.expand(3)
print(cir.get_state())
cir2 = UAnsatz(3)
cir2.ry(paddle.to_tensor(1,dtype='float64'),0)
cir2.run_state_vector()
print(cir2.get_state())
class TestPlotDensityGraph(unittest.TestCase):
def setUp(self):
self.func = plot_density_graph
self.x_np = (np.random.rand(8, 8) + np.random.rand(8, 8) * 1j)-0.5-0.5j
self.x_tensor = paddle.to_tensor(self.x_np)
def test_input_type(self):
self.assertRaises(TypeError, self.func, 1)
self.assertRaises(TypeError, self.func, [1, 2, 3])
def test_input_shape(self):
x = np.zeros((2, 3))
self.assertRaises(ValueError, self.func, x)
def test_ndarray_input_inputs(self):
res = self.func(self.x_np)
res.show()
def test_tensor_input(self):
res = self.func(self.x_tensor)
res.show()
if __name__ == '__main__':
test_density_matrix()
test_state_vector()
unittest.main()
\ No newline at end of file
from paddle_quantum.utils import img_to_density_matrix
import paddle
import matplotlib.image
import numpy as np
img_file = '/home/aistudio/f1.jpeg'
rho = (img_to_density_matrix(img_file))
#半正定
w,_=np.linalg.eig(rho)
print(all(w>=0))
#迹为1
print(np.trace(rho))
#shape为[2**n,2**n]
print(rho.shape)
from paddle_quantum.utils import Hamiltonian
h = Hamiltonian([(1, 'Z0, Z1')])
print(h.construct_h_matrix())
print(h.construct_h_matrix(4))
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 1, "execution_count": 14,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-05-16T03:41:44.449329Z", "end_time": "2021-05-16T03:41:44.449329Z",
...@@ -50,6 +50,8 @@ ...@@ -50,6 +50,8 @@
"import networkx as nx # networkx的版本 >= 2.5\n", "import networkx as nx # networkx的版本 >= 2.5\n",
"import matplotlib.pyplot as plt\n", "import matplotlib.pyplot as plt\n",
"from itertools import combinations\n", "from itertools import combinations\n",
"import warnings\n",
"warnings.filterwarnings(\"ignore\")\n",
"\n", "\n",
"# 将一个图形分割成两个有重合的分离顶点子图\n", "# 将一个图形分割成两个有重合的分离顶点子图\n",
"def NaiveLGP(g, k):\n", "def NaiveLGP(g, k):\n",
...@@ -103,7 +105,7 @@ ...@@ -103,7 +105,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 2, "execution_count": 15,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-05-16T03:41:44.839484Z", "end_time": "2021-05-16T03:41:44.839484Z",
...@@ -113,7 +115,7 @@ ...@@ -113,7 +115,7 @@
"outputs": [ "outputs": [
{ {
"data": { "data": {
"image/png": "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\n", "image/png": "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\n",
"text/plain": [ "text/plain": [
"<Figure size 1080x288 with 3 Axes>" "<Figure size 1080x288 with 3 Axes>"
] ]
...@@ -127,7 +129,7 @@ ...@@ -127,7 +129,7 @@
"n = 10\n", "n = 10\n",
"G = nx.Graph()\n", "G = nx.Graph()\n",
"G.add_nodes_from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])\n", "G.add_nodes_from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])\n",
"G.add_edges_from([(0, 1), (1, 2), (2, 3), (3, 4), (4, 5),\n", "G.add_edges_from([(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (1, 7),\n",
" (5, 6), (6, 7), (7, 8), (8, 9), (9, 0)])\n", " (5, 6), (6, 7), (7, 8), (8, 9), (9, 0)])\n",
" \n", " \n",
"k = 9 # 设定量子比特的最大数量\n", "k = 9 # 设定量子比特的最大数量\n",
...@@ -149,7 +151,7 @@ ...@@ -149,7 +151,7 @@
" a.margins(0.20)\n", " a.margins(0.20)\n",
"nx.draw_networkx(G, pos=nx.circular_layout(G), ax=ax[0], **options, node_color=node_color1)\n", "nx.draw_networkx(G, pos=nx.circular_layout(G), ax=ax[0], **options, node_color=node_color1)\n",
"nx.draw_networkx(S[0], pos=nx.circular_layout(S[0]), ax=ax[1], **options, node_color=node_color2)\n", "nx.draw_networkx(S[0], pos=nx.circular_layout(S[0]), ax=ax[1], **options, node_color=node_color2)\n",
"nx.draw_networkx(S[1], pos=nx.circular_layout(S[1]), ax=ax[2], **options, node_color=node_color3)" "nx.draw_networkx(S[1], pos=nx.circular_layout(S[1]), ax=ax[2], **options, node_color=node_color3)\n"
] ]
}, },
{ {
...@@ -170,7 +172,7 @@ ...@@ -170,7 +172,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 3, "execution_count": 16,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-05-16T03:41:46.108438Z", "end_time": "2021-05-16T03:41:46.108438Z",
...@@ -214,7 +216,7 @@ ...@@ -214,7 +216,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 4, "execution_count": 17,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-05-16T03:42:41.303385Z", "end_time": "2021-05-16T03:42:41.303385Z",
...@@ -227,11 +229,11 @@ ...@@ -227,11 +229,11 @@
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"第一个子图的最大割:\n", "第一个子图的最大割:\n",
"{'010xxxxxxx': 0.49999449162430293, '101xxxxxxx': 0.49999449162430293, '000xxxxxxx': 2.4202658690211183e-06, '111xxxxxxx': 2.420265869021086e-06, '110xxxxxxx': 1.544054913842632e-06, '011xxxxxxx': 1.5440549138425979e-06, '001xxxxxxx': 1.5440549138425754e-06, '100xxxxxxx': 1.5440549138424998e-06}\n", "{'01010101xx': 0.07887396513978905, '10010101xx': 0.07887396513978903, '01101010xx': 0.078873965139789, '10101010xx': 0.078873965139789, '10101101xx': 0.040906327139884305, '01010010xx': 0.0409063271398843, '01010110xx': 0.04004434869249364, '10100101xx': 0.04004434869249363, '01011010xx': 0.040044348692493625, '10101001xx': 0.040044348692493625}\n",
"第二个子图的最大割:\n", "第二个子图的最大割:\n",
"{'0x01010101': 0.14011845299520287, '1x10101010': 0.1401184529952028, '1x01010010': 0.04249785377879272, '0x10100101': 0.04249785377879272, '1x01011010': 0.0424978537787927, '0x10101101': 0.0424978537787927, '0x10101001': 0.036328002709709005, '1x01001010': 0.036328002709709, '0x10110101': 0.036328002709709, '1x01010110': 0.03632800270970896}\n", "{'0xxxxxx101': 0.4556003303152275, '1xxxxxx010': 0.45560033031522745, '1xxxxxx100': 0.0254542520553071, '0xxxxxx011': 0.025454252055307092, '0xxxxxx110': 0.010740876742244158, '1xxxxxx001': 0.010740876742244157, '1xxxxxx000': 0.0022930869455346486, '0xxxxxx111': 0.002293086945534646, '0xxxxxx100': 0.002293086945534642, '1xxxxxx011': 0.002293086945534638}\n",
"母图的最大割:\n", "母图的最大割:\n",
"{'0101010101': 0.14011845299520287, '1010101010': 0.1401184529952028, '0001010101': 2.4202658690211183e-06, '1110101010': 2.420265869021086e-06, '1101010110': 1.544054913842632e-06, '1101001010': 1.544054913842632e-06, '1101011010': 1.544054913842632e-06, '1101010010': 1.544054913842632e-06, '0110110101': 1.5440549138425979e-06, '0110101001': 1.5440549138425979e-06}\n" "{'0101010101': 0.07887396513978905, '1010101010': 0.078873965139789, '1010100100': 0.0254542520553071, '1010010100': 0.0254542520553071, '1010110100': 0.0254542520553071, '1001010100': 0.0254542520553071, '0101101011': 0.025454252055307092, '0101011011': 0.025454252055307092, '0101001011': 0.025454252055307092, '0110101011': 0.025454252055307092}\n"
] ]
} }
], ],
...@@ -281,16 +283,16 @@ ...@@ -281,16 +283,16 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"就以上例子来说,对于第一个子图而言,最有可能的几个最大割将包括 {'010xxxxxxx','101xxxxxxx'},而第二个子图最有可能的最大割将包括 {'1x10101010','0x01010101'}。这些字符串中的 'x' 代表不在这个子图却在母图的顶点。从这个例子中我们看到,分离顶点0和2在第一个子图中可能的最大割,'010xxxxxxx',中都属于 $S_0$,但它们在第二个子图的最大割,'1x10101010',中都属于 $S_1$,所以它们无法整合。(虽然因为 $S_0$ 和 $S_1$ 的对称性,我们可以把他们进行反转从而进行整合,但是没有必要这么做。)\n", "就以上例子来说,对于第一个子图而言,最有可能的几个最大割将包括 {'01010101xx', '10010101xx', '01101010xx', '10101010xx'},而第二个子图最有可能的最大割将包括 {'0xxxxxx101,'1xxxxxx010'}。这些字符串中的 'x' 代表不在这个子图却在母图的顶点。\n",
"\n", "\n",
"我们接着尝试整合第一个子图的第一个最大割 '010xxxxxxx' 和第二个子图的第二个最大割 '0x01010101',此最大割即是'101xxxxxxx' 的对称组。我们发现在这两个字符串所代表的最大割当中,分离顶点0和2都属于 $S_0$,我们也可以从下图第一张和第二张图中看出。所以我们可以整合这两个最大割并得到母图的最大割,'0101010101',如下图第三张图所示。\n", "从这个例子中我们看到,分离顶点 0 和 7 在第一个子图中可能的最大割,'01010101xx' 中分别属于 $S_0$ 和 $S_1$,它们在第二个子图的最大割,'0xxxxxx101',中也分别属于 $S_0$ 和 $S_1$,所以我们可以整合这两个最大割并得到母图的最大割,'0101010101',如下图第三张图所示。\n",
"\n", "\n",
"以下为图形展示,前两个图为两个子图的最大割实例,最右的图为母图的最大割。红色点和蓝色点分别表示被分在在 $S_0$ 和 $S_1$ 中的顶点,虚线表示被切割的边。" "以下为图形展示,前两个图为两个子图的最大割实例,最右的图为母图的最大割。红色点和蓝色点分别表示被分在在 $S_0$ 和 $S_1$ 中的顶点,虚线表示被切割的边。"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 5, "execution_count": 18,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-05-16T03:42:41.647686Z", "end_time": "2021-05-16T03:42:41.647686Z",
...@@ -300,7 +302,7 @@ ...@@ -300,7 +302,7 @@
"outputs": [ "outputs": [
{ {
"data": { "data": {
"image/png": "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\n", "image/png": "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GxF3dNp2SbZvx21bZ9u27rg923bJ9P9/B6xadFh+rrlSNb8LL0xFwj75BC6/HLbYotDeH3T7W1rVOZlqDRcCXYeb2tvTXY+TT07FKNZaC771Lbj66kLHmAbcU+U4zay1/Lm7B9dcExZeuGgVv+nGks5xZtY6fkUa2S6oxHNHH+CGCsfVG/+EIn2uPv4YXnsN9tsvlUMfNiwtAHvmmc57tgMXVTlO64GTqdZwC8Xu4IwenRY3fvghXHdd+sN9/vnOe00CLiKi2zvIZma9EcFk4GKKTEXeY48ZbfC68QVwe+WjM7M69hjwbrEHSzh3TANuj+DjKsRWmogg9QAdX/Dx7baDzTaD//4XXnkFpkyBQ7sULu0DXFHVOK1HSu+lNT3pVOAwCjXu7dkEYFki3qlsUGbW6iQWA/5N+eemsyI4obJRmVm9k9iTNCpduE9T99qBERE8XtGgekuaDXiPAr32SjAJuIGI3SsblPWWR6Zax8nAM3RXhrOwdmAvJ1JmVg0RvAXsQ+8L3EwCngZOq3hQZtYIrgT+SDfT/YoYD5yWeyIFEDEO2Jbe/w5TSWtFD6h0SNZ7TqZaRcRkUpfspyn9j3YCcDAR11ctLjNreRFcTRo5L/Xc1A48CWyeTRU0sxYTQQC7AndRbKpcV+3AecDpVQqr9yLuBXYmxVbKdLGJwCvAekSM6Wlnqz4nU60k4nNgfeAM4FMKFaVIlbUmAH8DNifi17UL0MxaVQS/ArYAHiWdgwqt0RwLfEy6EBoRgS8kzFpYdjNle+Bo0hqqsXRNSL4gJSrPAbtGcGyWiNWPiNtIjYjvJSVLhWYRjc1+LgK+RsT7tQvQuuM1U61KagO2BkYDi5I6iX8OPAT8nIiXcozOzFqYxJeAg4G1SY0tJ5KmtFwE3BnB1BzDM7M6JCHgm8BBwLKkZrZjgaeA8yN4KsfwSictCuxPmk00B+nG0nvAJcBNRPR2uYZVmZMpMzMzMzOzMnian5mZmZmZWRmcTJmZmZmZmZXByZSZmZmZmVkZnEyZmZmZmZmVwcmUmZmZmZlZGZxMmZmZmZmZlcHJlJmZmZmZWRmcTJmZmZmZmZXByZSZmZmZmVkZnEyZmZmZmZmVwcmUmZmZmZlZGZxMmZmZmZmZlcHJlJmZmZmZWRmcTJmZmZmZmZXByZSZmZmZmVkZnEyZmZmZmZmVwcmUmZmZmZlZGZxMmZmZmZmZlcHJlJmZmZmZWRmcTJmZmZmZmZXByZSZmZmZmVkZnEyZmZmZmZmVwcmUmZmZmZlZGZxMmZmZmZmZlcHJlJmZmZmZWRmcTJmZmZmZmZXByZSZmZmZmVkZnEyZmZmZmZmVwcmUmZmZmZlZGZxMmZmZmZmZlcHJlJmZmZmZWRmcTJmZmZmZmZXByZSZmZmZmVkZnEyZmZmZmZmVwcmUmZmZmZlZGf4fpfjM8bFtWsUAAAAASUVORK5CYII=\n",
"text/plain": [ "text/plain": [
"<Figure size 1080x288 with 3 Axes>" "<Figure size 1080x288 with 3 Axes>"
] ]
...@@ -311,8 +313,8 @@ ...@@ -311,8 +313,8 @@
], ],
"source": [ "source": [
"# 计算出的两个子图的最大割\n", "# 计算出的两个子图的最大割\n",
"strr1 = '010xxxxxxx'\n", "strr1 = '01010101xx'\n",
"strr2 = '0x01010101' \n", "strr2 = '0xxxxxx101' \n",
"strr = '0101010101'\n", "strr = '0101010101'\n",
"\n", "\n",
"# 图形示例展示\n", "# 图形示例展示\n",
...@@ -353,7 +355,7 @@ ...@@ -353,7 +355,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 6, "execution_count": 19,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-05-16T03:44:13.784486Z", "end_time": "2021-05-16T03:44:13.784486Z",
...@@ -365,8 +367,8 @@ ...@@ -365,8 +367,8 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"最有可能的 t 个图形 G 的最大割: {'0101010101': 947, '1010101010': 920, '1001010010': 150, '1001010100': 150, '1001010110': 150, '1101010010': 136, '1101010100': 136, '1101010110': 136, '1101010101': 135, '1001010101': 135}\n", "最有可能的 t 个图形 G 的最大割: {'1010101100': 419, '0101010011': 382, '0101011011': 368, '1010100100': 351, '0110101011': 303, '0101001011': 251, '1001010100': 247, '1010101010': 229, '0100101011': 227, '1011010100': 218}\n",
"量子近似优化分治算法找到的图形 G 的(最有可能的)最大割: 0101010101\n" "量子近似优化分治算法找到的图形 G 的(最有可能的)最大割: 1010101100\n"
] ]
} }
], ],
...@@ -413,7 +415,7 @@ ...@@ -413,7 +415,7 @@
" out_cnt = [(k, int(s * v / cnt_sum)) for (k, v) in out_cnt]\n", " out_cnt = [(k, int(s * v / cnt_sum)) for (k, v) in out_cnt]\n",
"\n", "\n",
" return out_cnt[0][0], dict(out_cnt)\n", " return out_cnt[0][0], dict(out_cnt)\n",
" \n", "\n",
"# 设定 量子近似优化算法 中的参数\n", "# 设定 量子近似优化算法 中的参数\n",
"p = 2 # 量子电路的层数\n", "p = 2 # 量子电路的层数\n",
"ITR = 100 # 训练迭代的次数\n", "ITR = 100 # 训练迭代的次数\n",
...@@ -456,7 +458,7 @@ ...@@ -456,7 +458,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 7, "execution_count": 20,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-05-16T03:44:54.150187Z", "end_time": "2021-05-16T03:44:54.150187Z",
...@@ -468,7 +470,7 @@ ...@@ -468,7 +470,7 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"最有可能的 t 个图形 G 的最大割:{'00101': 549, '10110': 512, '00001': 510, '11110': 501, '01001': 471, '11010': 457}\n" "最有可能的 t 个图形 G 的最大割:{'01001': 531, '00001': 504, '11110': 501, '10110': 494, '00101': 489, '11010': 481}\n"
] ]
} }
], ],
...@@ -494,7 +496,7 @@ ...@@ -494,7 +496,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 8, "execution_count": 21,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-05-11T07:06:44.690385Z", "end_time": "2021-05-11T07:06:44.690385Z",
...@@ -522,7 +524,7 @@ ...@@ -522,7 +524,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 9, "execution_count": 26,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-05-11T07:16:56.698522Z", "end_time": "2021-05-11T07:16:56.698522Z",
...@@ -538,29 +540,29 @@ ...@@ -538,29 +540,29 @@
"顶点编号 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n", "顶点编号 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n",
"\n", "\n",
"随机图形 1\n", "随机图形 1\n",
"边 = [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (2, 3), (2, 4), (2, 7), (3, 8), (3, 9), (4, 5), (5, 6), (5, 9), (6, 7), (6, 8)]\n", "边 = [(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 8), (1, 2), (1, 4), (1, 5), (1, 6), (1, 8), (1, 9), (2, 3), (2, 8), (3, 9), (4, 5), (4, 6), (5, 7), (5, 8), (6, 8), (7, 8)]\n",
"半正定规划找的最大割的上限: 14.773421849579332\n", "半正定规划找的最大割的上限: 16.366014900074795\n",
"量子近似优化分治算法找到的最大割分类: 0011011000, 最大割 = 14.0\n", "量子近似优化分治算法找到的最大割分类: 0010100011, 最大割 = 14.0\n",
"\n", "\n",
"随机图形 2\n", "随机图形 2\n",
"边 = [(0, 1), (0, 2), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (1, 4), (1, 6), (1, 7), (1, 8), (2, 4), (2, 5), (2, 7), (2, 9), (3, 6), (3, 8), (3, 9), (4, 5), (4, 6), (5, 7), (6, 9), (7, 9)]\n", "边 = [(0, 2), (0, 3), (0, 4), (0, 5), (0, 8), (1, 4), (1, 8), (1, 9), (2, 5), (2, 6), (2, 8), (3, 4), (3, 5), (3, 6), (3, 9), (4, 6), (4, 7), (4, 8), (5, 7), (6, 8), (7, 9), (8, 9)]\n",
"半正定规划找的最大割的上限: 17.637249299053625\n", "半正定规划找的最大割的上限: 17.401823913484183\n",
"量子近似优化分治算法找到的最大割分类: 1010011010, 最大割 = 15.0\n", "量子近似优化分治算法找到的最大割分类: 1100111001, 最大割 = 16.0\n",
"\n", "\n",
"随机图形 3\n", "随机图形 3\n",
"边 = [(0, 1), (0, 2), (0, 4), (0, 5), (0, 7), (0, 8), (0, 9), (1, 4), (1, 5), (2, 7), (2, 8), (2, 9), (3, 5), (3, 6), (3, 8), (3, 9), (4, 5), (4, 6), (4, 9), (5, 6), (5, 8), (5, 9), (6, 7), (7, 8), (7, 9)]\n", "边 = [(0, 1), (0, 2), (0, 3), (0, 5), (0, 7), (0, 8), (1, 3), (1, 5), (1, 6), (1, 8), (2, 3), (2, 4), (2, 6), (2, 7), (2, 8), (3, 4), (3, 5), (3, 7), (3, 8), (5, 6), (5, 7), (6, 7), (7, 8), (8, 9)]\n",
"半正定规划找的最大割的上限: 19.048588813917966\n", "半正定规划找的最大割的上限: 17.481389612347442\n",
"量子近似优化分治算法找到的最大割分类: 0010110100, 最大割 = 17.0\n", "量子近似优化分治算法找到的最大割分类: 0111000101, 最大割 = 17.0\n",
"\n", "\n",
"随机图形 4\n", "随机图形 4\n",
"边 = [(0, 3), (0, 6), (0, 7), (0, 8), (0, 9), (1, 2), (1, 5), (1, 7), (2, 6), (2, 7), (3, 4), (3, 7), (3, 8), (3, 9), (4, 5), (4, 8), (4, 9), (5, 6), (5, 9), (6, 7), (7, 9), (8, 9)]\n", "边 = [(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (1, 4), (1, 5), (1, 7), (2, 3), (2, 4), (2, 6), (2, 7), (2, 8), (2, 9), (3, 6), (3, 8), (3, 9), (4, 5), (5, 6), (5, 7), (5, 9), (6, 9), (8, 9)]\n",
"半正定规划找的最大割的上限: 16.551132643953018\n", "半正定规划找的最大割的上限: 19.247444317293844\n",
"量子近似优化分治算法找到的最大割分类: 1010110100, 最大割 = 16.0\n", "量子近似优化分治算法找到的最大割分类: 1110010000, 最大割 = 18.0\n",
"\n", "\n",
"随机图形 5\n", "随机图形 5\n",
"边 = [(0, 2), (0, 5), (0, 6), (0, 7), (0, 8), (1, 2), (1, 4), (1, 7), (2, 4), (2, 7), (2, 9), (3, 4), (3, 5), (3, 6), (3, 9), (4, 6), (4, 7), (4, 8), (5, 6), (5, 7), (5, 9), (6, 8), (7, 8), (8, 9)]\n", "边 = [(0, 3), (0, 5), (0, 6), (0, 7), (1, 3), (1, 5), (1, 7), (1, 8), (2, 7), (2, 9), (3, 4), (3, 6), (3, 7), (3, 8), (3, 9), (4, 6), (4, 7), (4, 8), (4, 9), (5, 7), (5, 8), (5, 9), (6, 7), (6, 9), (8, 9)]\n",
"半正定规划找的最大割的上限: 18.19997280321202\n", "半正定规划找的最大割的上限: 18.715743968566105\n",
"量子近似优化分治算法找到的最大割分类: 1100110001, 最大割 = 17.0\n" "量子近似优化分治算法找到的最大割分类: 1111110000, 最大割 = 17.0\n"
] ]
} }
], ],
...@@ -609,7 +611,7 @@ ...@@ -609,7 +611,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 10, "execution_count": 27,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-05-11T07:16:56.935061Z", "end_time": "2021-05-11T07:16:56.935061Z",
...@@ -619,7 +621,7 @@ ...@@ -619,7 +621,7 @@
"outputs": [ "outputs": [
{ {
"data": { "data": {
"image/png": "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TzoXjn983LmgXIC89NJLNGnShObNm9OyZUsWLFgAQIcOHWjQoMGZMsv33XcfCQkJZ96XXk+nadOm3HLLLZmWanZThw4dCGRX861bt9K0adM8r8cSvwlfqhA3AUa0h8NboeenTl0dNxSKgB6joGQlp5jb8YPuxBFg8+bNY8qUKSxZsoTly5fz66+/Ur36X72mPvvsM5YvX87y5cspWrTo30o3FCtWjLi4OFauXEmRIkUYMcL9Ci++1P4JBZb4TXhShW/vhcl3QZWWTnG1Ri7XXile1qn3c2wfLBnjbiwBsmfPHsqXL0/RokUBKF++PFWqVDlnuSJFivDqq6+yfft2li07d2Cb9u3bs3HjxnOmlyxZ8szzSZMmMWDAAAAGDBjAXXfdRWxsLPXr12fKlCkAjBkzhu7du9OhQwfq1avH888/f+b948aNo02bNrRs2ZI777zzTJIvWbIkjz76KC1atGDevHnnxPDpp5+eOTNZuHAhAIcOHeKGG26gefPmtGvXjuXLlwPw3HPP8dprr515b9OmTdm6dStbt26lUaNGDBkyhCZNmtC1a1dOnjwJcKY+UYsWLXj33Xez2Nu+s8RvwpOI00Wz47+cMsplqrkdkaNqaxgyAy59xJ3tf3ztuY+FI515p09kPH/pZ8784wfPnZeNrl27smPHDurXr88999zD7NmzM102IiKCFi1asHbt37u/pqSk8NNPP50pouarrVu3snDhQn744QfuuuuuM4ORL1y4kK+++orly5fz5ZdfsmjRItasWcPEiRP5448/iIuLIyIigs8+cz738ePHadu2LcuWLePSSy89ZzsnTpwgLi6O9957j0GDBgHw7LPP0qpVK5YvX87LL79Mv379so13w4YN3HvvvaxatYro6Gi++uorAAYOHMjbb7+d4Q9ibll3ThM+0tJg7ltQvj40vAYuvs/tiDJ2vieBHdoCiTvPLfMcRkqWLMnixYv5/fffmTlzJr169eKVV145c2R+Nu8SMidPnqRly5aAc8Q/ePDgHG27Z8+eFCpUiHr16lG7du0zPyhdunShXLlyANx0003MmTOHwoULs3jxYi688MIz265YsSLg/CD16NEj0+307t0bgMsuu4wjR46QkJDAnDlzziTuK664goMHD3LkSNZjIdSqVevM523dujVbt24lISGBhIQELrvsMgBuv/12fvrppxzt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\n", "image/png": "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\n",
"text/plain": [ "text/plain": [
"<Figure size 432x288 with 1 Axes>" "<Figure size 432x288 with 1 Axes>"
] ]
...@@ -693,6 +695,9 @@ ...@@ -693,6 +695,9 @@
], ],
"metadata": { "metadata": {
"celltoolbar": "Raw Cell Format", "celltoolbar": "Raw Cell Format",
"interpreter": {
"hash": "3b61f83e8397e1c9fcea57a3d9915794102e67724879b24295f8014f41a14d85"
},
"kernelspec": { "kernelspec": {
"display_name": "Python 3", "display_name": "Python 3",
"language": "python", "language": "python",
...@@ -708,7 +713,7 @@ ...@@ -708,7 +713,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.7.10" "version": "3.7.11"
}, },
"toc": { "toc": {
"base_numbering": 1, "base_numbering": 1,
......
...@@ -54,7 +54,8 @@ ...@@ -54,7 +54,8 @@
"import networkx as nx # version of networkx >= 2.5\n", "import networkx as nx # version of networkx >= 2.5\n",
"import matplotlib.pyplot as plt\n", "import matplotlib.pyplot as plt\n",
"from itertools import combinations\n", "from itertools import combinations\n",
"\n", "import warnings\n",
"warnings.filterwarnings(\"ignore\")\n",
"# Partition a graph into two subgraphs\n", "# Partition a graph into two subgraphs\n",
"def NaiveLGP(g, k):\n", "def NaiveLGP(g, k):\n",
" E = list(g.edges)\n", " E = list(g.edges)\n",
...@@ -117,7 +118,7 @@ ...@@ -117,7 +118,7 @@
"outputs": [ "outputs": [
{ {
"data": { "data": {
"image/png": "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\n", "image/png": "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\n",
"text/plain": [ "text/plain": [
"<Figure size 1080x288 with 3 Axes>" "<Figure size 1080x288 with 3 Axes>"
] ]
...@@ -131,7 +132,7 @@ ...@@ -131,7 +132,7 @@
"n = 10\n", "n = 10\n",
"G = nx.Graph()\n", "G = nx.Graph()\n",
"G.add_nodes_from([0,1,2,3,4,5,6,7,8,9])\n", "G.add_nodes_from([0,1,2,3,4,5,6,7,8,9])\n",
"G.add_edges_from([(0,1),(1,2),(2,3),(3,4),(4,5),(5,6),(6,7),(7,8),(8,9),(9,0)])\n", "G.add_edges_from([(0,1),(1,2),(2,3),(3,4),(4,5),(1, 7),(5,6),(6,7),(7,8),(8,9),(9,0)])\n",
" \n", " \n",
"k = 9 # Set qubit (vertex) limit\n", "k = 9 # Set qubit (vertex) limit\n",
"S = NaiveLGP(G,k) # Partition G into two subgrahs once\n", "S = NaiveLGP(G,k) # Partition G into two subgrahs once\n",
...@@ -217,7 +218,7 @@ ...@@ -217,7 +218,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 4, "execution_count": 5,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-05-11T06:52:48.693469Z", "end_time": "2021-05-11T06:52:48.693469Z",
...@@ -230,11 +231,11 @@ ...@@ -230,11 +231,11 @@
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"Max cut for the first partitioned subgraph: \n", "Max cut for the first partitioned subgraph: \n",
"{'010xxxxxxx': 0.49999449162430293, '101xxxxxxx': 0.49999449162430293, '111xxxxxxx': 2.420265869021529e-06, '000xxxxxxx': 2.42026586902126e-06, '001xxxxxxx': 1.5440549138418965e-06, '011xxxxxxx': 1.544054913841822e-06, '100xxxxxxx': 1.544054913841805e-06, '110xxxxxxx': 1.5440549138414785e-06}\n", "{'01010101xx': 0.07887396513978905, '10010101xx': 0.07887396513978903, '01101010xx': 0.078873965139789, '10101010xx': 0.078873965139789, '10101101xx': 0.040906327139884305, '01010010xx': 0.0409063271398843, '01010110xx': 0.04004434869249364, '10100101xx': 0.04004434869249363, '01011010xx': 0.040044348692493625, '10101001xx': 0.040044348692493625}\n",
"Max cut for the second partitioned subgraph: \n", "Max cut for the second partitioned subgraph: \n",
"{'1x10101010': 0.14011845299520345, '0x01010101': 0.14011845299520342, '1x01010010': 0.04249785377879293, '0x10101101': 0.04249785377879292, '1x01011010': 0.0424978537787929, '0x10100101': 0.042497853778792886, '0x10101001': 0.036328002709709185, '1x01010110': 0.03632800270970918, '0x10110101': 0.03632800270970918, '1x01001010': 0.036328002709709165}\n", "{'0xxxxxx101': 0.4556003303152275, '1xxxxxx010': 0.45560033031522745, '1xxxxxx100': 0.0254542520553071, '0xxxxxx011': 0.025454252055307092, '0xxxxxx110': 0.010740876742244158, '1xxxxxx001': 0.010740876742244157, '1xxxxxx000': 0.0022930869455346486, '0xxxxxx111': 0.002293086945534646, '0xxxxxx100': 0.002293086945534642, '1xxxxxx011': 0.002293086945534638}\n",
"Combined max cut for the original graph: \n", "Combined max cut for the original graph: \n",
"{'1010101010': 0.14011845299520345, '0101010101': 0.14011845299520342, '1110101010': 2.420265869021529e-06, '0001010101': 2.42026586902126e-06, '0010110101': 1.5440549138418965e-06, '0010101001': 1.5440549138418965e-06, '0010100101': 1.5440549138418965e-06, '0010101101': 1.5440549138418965e-06, '0110110101': 1.544054913841822e-06, '0110101001': 1.544054913841822e-06}\n" "{'0101010101': 0.07887396513978905, '1010101010': 0.078873965139789, '1010100100': 0.0254542520553071, '1010010100': 0.0254542520553071, '1010110100': 0.0254542520553071, '1001010100': 0.0254542520553071, '0101101011': 0.025454252055307092, '0101011011': 0.025454252055307092, '0101001011': 0.025454252055307092, '0110101011': 0.025454252055307092}\n"
] ]
} }
], ],
...@@ -282,14 +283,14 @@ ...@@ -282,14 +283,14 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"The top several possible max cuts for the first subgraph include {'010xxxxxxx','101xxxxxxx'} and those for the second subgraph include {'1x10101010','0x01010101'}, where 'x' indicates those missing nodes in the subgraph. Shared nodes $0$ and $2$ are all '0's in the first possibility of the first subgraph, i.e. '010xxxxxxx', while they are all '1's in the first possibility of the second subgraph, i.e. '1x10101010', so they cannot combine. (Note that although we can flip 0s and 1s in this situation by symmetry, it is not necessary). We then try to combine '010xxxxxxx' (first possibility of the first subgraph) and '0x01010101' (second possibility of the second subgraph). It is clear that the shared nodes $0$ and $2$ are all '0's in both subgraphs as shown below in the left and middle figure, so we combine these two max cuts and get '0101010101' for the original cycle of six as shown below in the right.\n", "The top several possible max cuts for the first subgraph include {'01010101xx', '10010101xx', '01101010xx', '10101010xx'} and those for the second subgraph include {'0xxxxxx101,'1xxxxxx010'}, where 'x' indicates those missing nodes in the subgraph. From this example we see that the possible maximal cuts of separated vertices 0 and 7 in the first subgraph, '01010101xx', belong to $S_0$ and $S_1$, respectively. And they also belong to $S_0$ and $S_1$, respectively, in the maximal cut of the second subgraph, '0xxxxxx101'. so we can integrate these two maximal cuts and get the maximal cut of the original graph, ' 0101010101', as shown in the third diagram below.\n",
"\n", "\n",
"Graph illustration is shown below. The left and middle subgraphs are subgraphs with approximate max cuts, where red and blue nodes represent $S_0$ and $S_1$ and dashed lines represent cuts." "Graph illustration is shown below. The left and middle subgraphs are subgraphs with approximate max cuts, where red and blue nodes represent $S_0$ and $S_1$ and dashed lines represent cuts."
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 5, "execution_count": 6,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-05-11T06:52:49.021611Z", "end_time": "2021-05-11T06:52:49.021611Z",
...@@ -299,7 +300,7 @@ ...@@ -299,7 +300,7 @@
"outputs": [ "outputs": [
{ {
"data": { "data": {
"image/png": "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\n", "image/png": "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GxF3dNp2SbZvx21bZ9u27rg923bJ9P9/B6xadFh+rrlSNb8LL0xFwj75BC6/HLbYotDeH3T7W1rVOZlqDRcCXYeb2tvTXY+TT07FKNZaC771Lbj66kLHmAbcU+U4zay1/Lm7B9dcExZeuGgVv+nGks5xZtY6fkUa2S6oxHNHH+CGCsfVG/+EIn2uPv4YXnsN9tsvlUMfNiwtAHvmmc57tgMXVTlO64GTqdZwC8Xu4IwenRY3fvghXHdd+sN9/vnOe00CLiKi2zvIZma9EcFk4GKKTEXeY48ZbfC68QVwe+WjM7M69hjwbrEHSzh3TANuj+DjKsRWmogg9QAdX/Dx7baDzTaD//4XXnkFpkyBQ7sULu0DXFHVOK1HSu+lNT3pVOAwCjXu7dkEYFki3qlsUGbW6iQWA/5N+eemsyI4obJRmVm9k9iTNCpduE9T99qBERE8XtGgekuaDXiPAr32SjAJuIGI3SsblPWWR6Zax8nAM3RXhrOwdmAvJ1JmVg0RvAXsQ+8L3EwCngZOq3hQZtYIrgT+SDfT/YoYD5yWeyIFEDEO2Jbe/w5TSWtFD6h0SNZ7TqZaRcRkUpfspyn9j3YCcDAR11ctLjNreRFcTRo5L/Xc1A48CWyeTRU0sxYTQQC7AndRbKpcV+3AecDpVQqr9yLuBXYmxVbKdLGJwCvAekSM6Wlnqz4nU60k4nNgfeAM4FMKFaVIlbUmAH8DNifi17UL0MxaVQS/ArYAHiWdgwqt0RwLfEy6EBoRgS8kzFpYdjNle+Bo0hqqsXRNSL4gJSrPAbtGcGyWiNWPiNtIjYjvJSVLhWYRjc1+LgK+RsT7tQvQuuM1U61KagO2BkYDi5I6iX8OPAT8nIiXcozOzFqYxJeAg4G1SY0tJ5KmtFwE3BnB1BzDM7M6JCHgm8BBwLKkZrZjgaeA8yN4KsfwSictCuxPmk00B+nG0nvAJcBNRPR2uYZVmZMpMzMzMzOzMnian5mZmZmZWRmcTJmZmZmZmZXByZSZmZmZmVkZnEyZmZmZmZmVwcmUmZmZmZlZGZxMmZmZmZmZlcHJlJmZmZmZWRmcTJmZmZmZmZXByZSZmZmZmVkZnEyZmZmZmZmVwcmUmZmZmZlZGZxMmZmZmZmZlcHJlJmZmZmZWRmcTJmZmZmZmZXByZSZmZmZmVkZnEyZmZmZmZmVwcmUmZmZmZlZGZxMmZmZmZmZlcHJlJmZmZmZWRmcTJmZmZmZmZXByZSZmZmZmVkZnEyZmZmZmZmVwcmUmZmZmZlZGZxMmZmZmZmZlcHJlJmZmZmZWRmcTJmZmZmZmZXByZSZmZmZmVkZnEyZmZmZmZmVwcmUmZmZmZlZGZxMmZmZmZmZlcHJlJmZmZmZWRmcTJmZmZmZmZXByZSZmZmZmVkZnEyZmZmZmZmVwcmUmZmZmZlZGf4fpfjM8bFtWsUAAAAASUVORK5CYII=\n",
"text/plain": [ "text/plain": [
"<Figure size 1080x288 with 3 Axes>" "<Figure size 1080x288 with 3 Axes>"
] ]
...@@ -310,8 +311,8 @@ ...@@ -310,8 +311,8 @@
], ],
"source": [ "source": [
"# Computed max cut for two subgraphs\n", "# Computed max cut for two subgraphs\n",
"strr1 = '010xxxxxxx'\n", "strr1 = '01010101xx'\n",
"strr2 = '0x01010101' \n", "strr2 = '0xxxxxx101' \n",
"strr = '0101010101'\n", "strr = '0101010101'\n",
"\n", "\n",
"# Show graph illustration\n", "# Show graph illustration\n",
...@@ -352,7 +353,7 @@ ...@@ -352,7 +353,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 6, "execution_count": 7,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-05-11T06:54:04.788730Z", "end_time": "2021-05-11T06:54:04.788730Z",
...@@ -364,8 +365,8 @@ ...@@ -364,8 +365,8 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"First t possible approximate maxcut for graph G: {'1010101010': 938, '0101010101': 878, '0110101001': 160, '0110101011': 160, '1001010110': 152, '1001010100': 152, '1001010010': 145, '1101010010': 137, '1101010110': 137, '1101010100': 137}\n", "First t possible approximate maxcut for graph G: {'0101011011': 408, '0101010011': 393, '1010101100': 386, '1010100100': 350, '1001010100': 257, '0101010101': 250, '1011010100': 248, '0101001011': 244, '0110101011': 235, '0100101011': 225}\n",
"Max cut found by DC-QAOA algorithms: 1010101010\n" "Max cut found by DC-QAOA algorithms: 0101011011\n"
] ]
} }
], ],
...@@ -461,7 +462,7 @@ ...@@ -461,7 +462,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 7, "execution_count": 8,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-05-11T06:54:45.016920Z", "end_time": "2021-05-11T06:54:45.016920Z",
...@@ -473,7 +474,7 @@ ...@@ -473,7 +474,7 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"First t possible approximate maxcut for graph G: {'00001': 532, '00101': 501, '11110': 496, '01001': 496, '10110': 492, '11010': 483}\n" "First t possible approximate maxcut for graph G: {'11010': 535, '01001': 515, '00001': 495, '11110': 495, '10110': 488, '00101': 472}\n"
] ]
} }
], ],
...@@ -499,7 +500,7 @@ ...@@ -499,7 +500,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 8, "execution_count": 10,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-05-11T06:54:47.679276Z", "end_time": "2021-05-11T06:54:47.679276Z",
...@@ -527,7 +528,7 @@ ...@@ -527,7 +528,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 9, "execution_count": 15,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-05-11T07:02:35.277145Z", "end_time": "2021-05-11T07:02:35.277145Z",
...@@ -543,29 +544,29 @@ ...@@ -543,29 +544,29 @@
"Node = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n", "Node = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n",
"\n", "\n",
"Random graph 1\n", "Random graph 1\n",
"Edges = [(0, 2), (0, 6), (0, 7), (0, 8), (1, 3), (1, 5), (1, 6), (1, 8), (1, 9), (2, 3), (2, 4), (2, 6), (2, 8), (2, 9), (3, 4), (3, 6), (3, 7), (3, 8), (3, 9), (4, 9), (5, 8), (7, 9), (8, 9)]\n", "Edges = [(0, 1), (0, 5), (0, 6), (0, 7), (1, 3), (1, 4), (1, 6), (1, 8), (1, 9), (2, 3), (2, 4), (2, 6), (2, 8), (3, 5), (3, 6), (3, 8), (4, 5), (4, 7), (4, 8), (5, 8), (5, 9), (6, 7), (6, 8), (6, 9), (7, 8), (7, 9)]\n",
"SDP upper bound: 17.750789460578076\n", "SDP upper bound: 21.03787674994891\n",
"DC-QAOA node partition: 1001011001, max cut = 17.0\n", "DC-QAOA node partition: 1001100011, max cut = 21.0\n",
"\n", "\n",
"Random graph 2\n", "Random graph 2\n",
"Edges = [(0, 1), (0, 3), (0, 6), (1, 2), (1, 3), (2, 5), (2, 6), (2, 7), (3, 5), (3, 6), (3, 8), (3, 9), (4, 6), (4, 7), (4, 8), (4, 9), (5, 7), (5, 8), (6, 7), (6, 8), (7, 9)]\n", "Edges = [(0, 1), (0, 2), (0, 4), (0, 8), (0, 9), (1, 2), (1, 3), (1, 5), (1, 6), (1, 7), (1, 8), (2, 3), (2, 6), (2, 8), (3, 8), (4, 8), (4, 9), (5, 9), (6, 8), (6, 9)]\n",
"SDP upper bound: 16.64755118085844\n", "SDP upper bound: 16.028382190698274\n",
"DC-QAOA node partition: 1100111001, max cut = 15.0\n", "DC-QAOA node partition: 1011011100, max cut = 14.0\n",
"\n", "\n",
"Random graph 3\n", "Random graph 3\n",
"Edges = [(0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (2, 3), (2, 4), (2, 6), (2, 7), (2, 8), (4, 5), (4, 7), (4, 9), (5, 7), (5, 8), (5, 9), (6, 7), (7, 8), (8, 9)]\n", "Edges = [(0, 2), (0, 5), (0, 6), (0, 7), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 9), (2, 3), (2, 5), (2, 6), (2, 9), (3, 4), (3, 6), (3, 7), (4, 6), (4, 7), (4, 8), (5, 6), (5, 7), (6, 7)]\n",
"SDP upper bound: 19.402766322145684\n", "SDP upper bound: 17.0971057189657\n",
"DC-QAOA node partition: 1101100010, max cut = 18.0\n", "DC-QAOA node partition: 0010111100, max cut = 15.0\n",
"\n", "\n",
"Random graph 4\n", "Random graph 4\n",
"Edges = [(0, 1), (0, 2), (0, 5), (0, 6), (0, 7), (0, 9), (1, 5), (1, 6), (1, 7), (1, 9), (2, 3), (2, 6), (2, 8), (3, 5), (3, 6), (3, 8), (3, 9), (4, 5), (4, 6), (4, 7), (4, 9), (5, 6), (5, 7), (5, 8), (6, 7), (6, 8), (7, 8)]\n", "Edges = [(0, 1), (0, 2), (0, 3), (0, 4), (0, 6), (0, 7), (0, 8), (0, 9), (1, 7), (1, 8), (1, 9), (2, 3), (2, 6), (2, 7), (2, 9), (3, 4), (3, 5), (3, 7), (3, 8), (3, 9), (4, 7), (4, 8), (5, 6), (5, 8), (5, 9), (6, 7), (6, 9), (7, 8), (7, 9)]\n",
"SDP upper bound: 20.999869854784496\n", "SDP upper bound: 20.153931079390457\n",
"DC-QAOA node partition: 0010011011, max cut = 18.0\n", "DC-QAOA node partition: 1111101000, max cut = 17.0\n",
"\n", "\n",
"Random graph 5\n", "Random graph 5\n",
"Edges = [(0, 1), (0, 4), (0, 7), (1, 2), (1, 3), (1, 6), (1, 7), (1, 8), (1, 9), (2, 4), (2, 7), (2, 9), (3, 7), (3, 9), (4, 5), (4, 6), (4, 8), (5, 6), (5, 7), (5, 8), (6, 7), (6, 8), (6, 9), (7, 9), (8, 9)]\n", "Edges = [(0, 1), (0, 2), (0, 6), (1, 2), (1, 4), (1, 5), (1, 7), (1, 8), (2, 3), (2, 4), (2, 5), (2, 6), (2, 8), (2, 9), (3, 6), (3, 7), (3, 8), (4, 7), (4, 9), (5, 7), (5, 8), (6, 7), (6, 9), (7, 9), (8, 9)]\n",
"SDP upper bound: 19.454398132157152\n", "SDP upper bound: 18.82486962324589\n",
"DC-QAOA node partition: 1011011001, max cut = 18.0\n" "DC-QAOA node partition: 1010000110, max cut = 18.0\n"
] ]
} }
], ],
...@@ -612,7 +613,7 @@ ...@@ -612,7 +613,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 11, "execution_count": 16,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-05-11T07:02:35.547590Z", "end_time": "2021-05-11T07:02:35.547590Z",
...@@ -622,7 +623,7 @@ ...@@ -622,7 +623,7 @@
"outputs": [ "outputs": [
{ {
"data": { "data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAX4AAAEWCAYAAABhffzLAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Z1A+gAAAACXBIWXMAAAsTAAALEwEAmpwYAABD70lEQVR4nO3dd3hUZfbA8e8hBELvIj10pAaIVAuKYgFFRFFEaTbAhm1XXevq2n7qKiJNQFAQUVBEUFkELHQJhI7Se4fQa3J+f9wJDCFlCJm5U87nee7DzK1nJsyZO+9973lFVTHGGBM5crkdgDHGmMCyxG+MMRHGEr8xxkQYS/zGGBNhLPEbY0yEscRvjDERxhK/MX4gIjVFJFFEDonI427HY4w3S/zmgonIBhE5KSIl08xfJCIqIrF+Om4TEflRRJJEZJ+IzBeRHj5uO0JE3shiHRWRIyJyWES2isgHIhKVzXD/AcxQ1UKq2i+b+zDGLyzxm+xaD3ROfSIi9YD8/jqYiDQHpgO/AdWAEkBv4KYcPlQDVS0ItAbuAR68wDhzex5WApZnJwCvfRjjF5b4TXZ9AXT1et4N+Nx7BRFp6/kVcFBENovIq17L7hKR9SJS2PP8JhHZISKlMjje/wEjVfUdVd2jjgRV7eTZvruIzExzfBWRaiLyENAF+IfnbP6HrF6cqq4C/gDqevbVztN0kyQis0WkvtdxNojIP0VkCXBERKYD1wD9PcerISJFRORzEdktIhtF5EURyeUV+ywR+a+I7AVe9fxCGSAiP3n2MUtELhWRD0Vkv4isEpGGXjE8JyJrPU1LK0Skg9ey7iIyU0Te82y7XkRu8lpeXEQ+E5FtnuUTvJa197zug5793+iZX0REhonIds+vozcu4teRCTRVtcmmC5qADcB1wF/AZUAUsAXnLFeBWM96rYB6OCcY9YGdwG1e+xkNjMA5e98GtMvgePmBZOCaTGLqDsxMM0+Bap7HI4A3snhd3uvXBnYA9wMNgV1AU89r7eZ5D/J6vR+JQAUgn2fer8ADXvv+HPgeKATEAn8D93vFfhp4DMgN5PPEuwdoDMTg/NpZj/NlGwW8gdOUlLr/O4Gynvf6LuAIUMZr/6dwfr1E4fxS2gaIZ/lkYCxQDIgGrvbMbwIcAK737LccUMuz7DtgMFAAuASYDzzs9v9Nm3z8DLsdgE2hN3E28b8IvAXcCEz1JK0ziT+d7T4E/uv1vCiwCVgKDM7keOU8+62VyTo5lfgPAvuBtZ7kmgsYCLyeZt2/vBLkBqBnmuVnEr8n2Z4Eanstfxj41Sv2TWm2HwF86vX8MWCl1/N6QFImryURaO+1/zVey/J7XuulQBkgBSiWzj4Ge/+9vOaXBk7g+ZLzzOuM1xeRTcE9WVuiuRhfAL8DlUnTzAMgIk2Bt3GaS/IAeYFvUperapKIfAM8BXT02u4F4AXP01Ge5Sk4SWqVP16Il0aqusZ7hohUArqJyGNes/PgnGGn2pzJPkvinElv9Jq3EecLLbPtd3o9PpbO84JeMXbFeZ9iPbMKeo6bakfqA1U9KiKp6xQH9qnq/nSOXwH4MZ35lTyvZ7tnP+B8QWb2HpggYm38JttUdSNO88PNwLfprPIlMBGooKpFgEHAmUwhInFAT2AMcKbni6q+qaoFPVMvVT0KzMHryyEdR/C6uCwil6YN9wJeWlqbgf+oalGvKb+qjvFx/3twmloqec2rCGzNifg8X0yfAo8CJVS1KLAMr/c6E5uB4iJSNINlVTOYfwIo6fV+FFbVOtmJ3wSeJX5zse4HrlXVI+ksK4RzNnlcRJrg9JIBQERicM7mXwB6AOVEpE8mx/kH0F1EnhWREp59NBCRrzzLFwN1RCTOs+9X02y/E6hy4S8PcJJqLxFpKo4CngvXhXzZWFWTga+B/4hIIU+ifgrn9eeEAjhfHLsBPF1c6/oY23bgJ2CAiBQTkWgRucqzeBjQQ0Rai0guESknIrU82/wPeF9ECnuWVRWRq3Po9Rg/s8RvLoqqrlXVBRks7gP8W0QOAS/jJL9UbwGbVXWgqp4A7gXeEJHqGRxnNnCtZ1onIvuAIXiaIlT1b+DfwC/AamBmml0MA2p7euVMuMDXuADnwmh/nPb/NTjt5hfiMZxfJes8sX0JDL/AfWQU3wrgfZxfRTtx2v9nXcAu7sP5RbIK5yJ2X89+5+N8Kf8X5yLvb5z91dIVp7lrBc57Mg6nKc6EgNSr+sYYYyKEnfEbY0yEscRvjDERxhK/McZEGEv8xhgTYULiBq6SJUtqbGys22EYY0xISUhI2KOq59W/ConEHxsby4IFGfUYNMYYkx4R2ZjefGvqMcaYCGOJ3xhjIowlfmOMiTAh0cafnlOnTrFlyxaOHz/udijGj2JiYihfvjzR0dFuh2JM2AjZxL9lyxYKFSpEbGwsXqVhTRhRVfbu3cuWLVuoXLmy2+EYEzb81tQjIhVEZIZnGLjlIvKEZ/6dnucpIhKf3f0fP36cEiVKWNIPYyJCiRIl7FedMTnMn2f8p4GnVXWhp3xtgohMxakTfjvO6D4XxZJ++LO/sTE5z29n/Kq6XVUXeh4fAlYC5VR1par+5a/jGmOC1KEdMG8wHEtyO5KIF5BePSISizNg9bwL2OYhEVkgIgt2797tt9guRlRUFHFxcdSpU4cGDRrw/vvvk5KScmb5/Pnzueqqq6hZsyYNGzbkgQce4OjRo+nua8KECdSvX59atWpRt25dxo0bd87y06dPU6pUKZ577rlz5h84cICuXbtSrVo1qlatSteuXTlw4MA56/Tt25dy5cqdE5sxATfpKfjpHzCgOaye6nY0kc3fg/rijOuZANyeZv6vQLwv+2jcuLGmtWLFivPmBVqBAgXOPN65c6e2bt1aX375ZVVV3bFjh1asWFFnz559Zp1vvvlGd+zYcd5+EhMTtWrVqrpu3TpVVV23bp1WqVJFFyxYcGadH3/8UVu0aKFVqlTRlJSUM/M7duyor7zyypnnL7/8st5xxx1nnicnJ2vFihW1adOmOn369It/0S4Ihr+1yaaj+1UP73Ye79ugunyCav8mqq8UVp3QR/VYkqvhhTtggaaXl9ObmVMTzoDMU4Cn0lkWVolfVXXt2rVavHhxTUlJ0Zdeeklfeukln/Zz77336rBhw86ZN3ToUO3cufOZ5/fdd5+OHTtWW7VqpbNmzVJV1dWrV2tsbKyePn36zHqnT5/W2NhYXbNmjaqqTps2TW+66SYdMWKEPvjgg9l6nW4Lhr+1yYa1M1Tfv0z1y87nzj91XHXqq6qvFVddP9OV0CJFRonfbxd3xbkqNwxYqaof+Os4AK/9sJwV2w7m6D5rly3MK7dc2NjRVapUITk5mV27drFs2TK6devm03bLly/nmWeeOWdefHw8H3/8MeD0YPrll18YPHgwSUlJjBkzhhYtWrBixQri4uKIioo6s11q89Py5cupWrUqY8aMoXPnzrRv354XXniBU6dOWZ9441+njsEvr8K8QVCiOlz19LnLc+eF616By++HIuWdeSu+hyrXQEzhgIcbifzZxt8SZyzPa0Uk0TPdLCIdRGQL0ByYLCJT/BhDWJg0aRLXXHMN+fLlo2PHjkyYMIHk5OQstzt58iQ//vgjt912G4ULF6Zp06ZMmWJvt/Gj3X/D4KucpN/kYXj4dyjXOP11U5P+ga0w7n6n7X/t9MDFGsH8dsavqjOBjPrifZeTx7rQM3N/WbduHVFRUVxyySXUqVOHhIQE2rdvf956N9xwAzt37iQ+Pp6hQ4dSu3ZtEhISaNCgwZl1EhISiI93bnMYM2YMM2fOJLU09d69e5k+fTq1a9cmMTGRlJQUcuVyvsNTUlJITEykdu3aTJkyhaSkJOrVqwfA0aNHyZcvH+3atfPzO2EiVoGSkKcg3PcdVL3Wt22KlIOeP8OE3vBFB2jcHa5/3c7+/Sm99p9gm0KhjX/Xrl16/fXXn3dxd+7cuWfWGT9+fLoXdxctWqTVqlXT9evXq6rq+vXrtV69erpq1So9cOCAlipVSo8fP35m/eHDh2uPHj1UVbVDhw762muvnVn22muv6e23366qqp07d9Yvv/zyzLLDhw9rqVKl9MiRIznw6gMnGP7WJhO7V6tOfEL19EnnuVfngwty8pjqlBdVXy2q2q/R2f2ZbMONi7s5NQVr4s+VK5c2aNBAa9eurfXr19f/+7//0+Tk5DPLZ8+erVdccYXWqFFDa9WqpQ899FCGSXf8+PFat25drV69ukZHR+vMmc5FrxEjRuhdd911zrp79+7VkiVL6vHjx3Xfvn3apUsXrVKlilapUkW7dOmi+/fv1yNHjmixYsX0wIED52zboUMH/eqrr3L4nfCvYPhbm3SkpKjOG6L6emnVtyqq7liWM/vdNE914Rdnn588ljP7jUAZJX5xlgW3+Ph4TTsQy8qVK7nssstcisi/nnvuOebNm8eUKVPIkyeP2+G4Lpz/1iHr4Hb4/hFYOw2qtob2/aFw2Zw/zorvYcqLzv6rXJ3z+w9zIpKgqueVxgnZIm3h7O2333Y7BGMy90132LEE2r4P8feDv0prFCoDUdHw+a1w+QNw3WuQt6B/jhVBLPEbY3xzdB9E5XESb9v3IXcMlKzm32NWaAK9ZsL0N2DuAOeO39sGQOwV/j1umLOBWIwxWVs7HQa2gKkvOc8vrev/pJ8qT3648U3o8RPkinKamcxFsTN+Y0zGTh6FX16B+UOgZE1o1NW9WCo1h95znBvAABZ/BUUqQGxL92IKUZb4jTHp27HMacvfuxqa9YHWL0N0Pndjio5x/k1Jhln9YNdyaNrLiS1PAXdjCyHW1GOMSV+eAk7TSteJcONb7id9b7mi4IGpzt3B8wbBwJawcbbbUYUMS/wX4T//+Q916tShfv36xMXFMW+eU3W6VatW1KxZ80yZ5UcffZSkpKQz26XW06lbty533nlnhqWa3dSqVSvSdqH1pw0bNlC3bt2AHc9kYPffTp0dVShe2WlaCdZulHkKwM3vQvfJgMKItrBvvdtRhQRL/Nk0Z84cJk2axMKFC1myZAm//PILFSpUOLN89OjRLFmyhCVLlpA3b95zSjfky5ePxMREli1bRp48eRg0aJAbL+EcvtT+MWEsJcUZJGXwlZAwApI2OfNzhUCKiL0Ces2COz5zvqwAkja7G1OQC4G/anDavn07JUuWJG9e50JTyZIlKVv2/BtY8uTJw7vvvsumTZtYvHjxecuvvPJK1qxZc978ggXP9lUeN24c3bt3B6B79+706tWL+Ph4atSowaRJkwAYMWIE7du3p1WrVlSvXp3XXnvtzPajRo2iSZMmxMXF8fDDD59J8gULFuTpp5+mQYMGzJkz57wYvvjiizO/TObPnw/Avn37uO2226hfvz7NmjVjyZIlALz66qu89957Z7atW7cuGzZsYMOGDVx22WU8+OCD1KlThzZt2nDs2DGAM/WJGjRowCeffJLJu2386sBWGNXBGSQl9kroMxeKVXI7qguTtyDUuc15vPlP6BcHP7/gXJw25wmfxP9Z2/On+Z86y04eTX/5otHO8iN7z1+WhTZt2rB582Zq1KhBnz59+O233zJcNyoqigYNGrBq1apz5p8+fZqffvrpTBE1X23YsIH58+czefJkevXqdWYw8vnz5zN+/HiWLFnCN998w4IFC1i5ciVjx45l1qxZJCYmEhUVxejRzus+cuQITZs2ZfHixVxxxfn9oo8ePUpiYiIDBgygZ8+eALzyyis0bNiQJUuW8Oabb9K1a9a9PFavXs0jjzzC8uXLKVq0KOPHjwegR48efPzxx+l+IZoASUlxCqNtng/t/gtdvoFCl7od1cW5pBY06gZzP4FBV8Amnwf+ixjhk/gDrGDBgiQkJDBkyBBKlSrFXXfdxYgRIzJc37s0xrFjx4iLiyM+Pp6KFSty//33X9CxO3XqRK5cuahevTpVqlQ584Vy/fXXU6JECfLly8ftt9/OzJkzmTZtGgkJCVx++eXExcUxbdo01q1bBzhfSB07dszwOJ07dwbgqquu4uDBgyQlJTFz5kzuu+8+AK699lr27t3LwYOZj4VQuXJl4uLiAGjcuDEbNmwgKSmJpKQkrrrqKoAz+zQBcnQfJJ92mnJu+dC5SSq+p//uwA2kvIWg3QfQ9XtIPgXDb4Bpr7sdVVAJn+6cPSZnvCxP/syXFyiR+fIMREVF0apVK1q1akW9evUYOXLkmSYZb8nJySxduvRMvZnUNv7MiNcHMPWMPr1l3s/Tm6+qdOvWjbfeeuu8Y8TExJwziEtmMaT33Fvu3LnPGdPXO+bU5jBw3rPUph7jktW/OHV2Ln8Arn4WKrVwOyL/qNIK+syG/71kJZ7TsDP+bPrrr79YvXr1meeJiYlUqnR+u+ipU6d4/vnnqVChAvXr1/d5/6VLl2blypWkpKTw3XfnDl/wzTffkJKSwtq1a1m3bh01a9YEYOrUqezbt49jx44xYcIEWrZsSevWrRk3bhy7du0CnDb6jRs3+hTD2LFjAZg5cyZFihShSJEiXHnllWeain799VdKlixJ4cKFiY2NZeHChQAsXLiQ9esz711RtGhRihYtysyZMwHO7NP40ckjzoDnoztCvqJQo43bEflf3kLOL5oWjzvPV0x0vghOHc90s3AXPmf8AXb48GEee+wxkpKSyJ07N9WqVWPIkCFnlnfp0oW8efNy4sQJrrvuOr7//vsL2v/bb79Nu3btKFWqFPHx8Rw+fPjMsooVK9KkSRMOHjzIoEGDiIlxbmpp0qQJHTt2ZMuWLdx7771nBnJ54403aNOmDSkpKURHR/PJJ5+k+yWVVkxMDA0bNuTUqVMMHz4ccC7i9uzZk/r165M/f35GjhwJQMeOHfn888+pU6cOTZs2pUaNGlnu/7PPPqNnz56ICG3aREASctO2Rc4oV/vWQfNH4dqXzt4MFQlSf61uWwSz+8HfP8NtA6H8eYUrI4KVZQ4x3bt3p127dtxxxx3nzB8xYgQLFiygf//+LkXmP5H6t85RWxOcxH/rx1D5SrejcdeaaTDxcTi0DVo8Bq1eCNsvwYzKMltTjzHhatcqmP2x87hcY3h0gSV9gGqtnbb/hvfCrI9gzS9uRxRwdsZvgp79rS9QSopTxuCXV5027kfmOx0YzPm2LoSyDZ2moE1znce582a9XYgIyzP+UPjSMhfH/sYXKGkzfNEepjwPVa+B3rMt6WemXCMn6R/eDZ/fBoOvdr4MwlzIJv6YmBj27t1riSGMqSp79+49c/HaZOH0CRjWxklct/SDzl9BodJuRxUaCpaCu76A40kw9Dqn3//pE25H5Tch29Rz6tQptmzZcl4fdxNeYmJiKF++PNHR0W6HEryOH4C8hZ0z179+glK1ztasMRfmWBJMeQESR0PpuvDAtJC+8Bt2Y+5GR0dTubL95zYRbvVU52as1i87Fytr3uR2RKEtX1FnaMfa7WH7Yq/6/ymhUbDOR357JSJSQURmiMgKEVkuIk945hcXkakistrzbzF/xWBM2DpxGH7oC6PvgPwl4FLfbw40PqhxA1z9D+fxpnkw5GrniyBMZJn4ReROX+al4zTwtKrWBpoBj4hIbeA5YJqqVgemeZ4bY3y1+U+n+FjCCKcf+oMzoIwlfr85dRQO74RPr4UZb8Lpk25HdNF8OeN/3sd551DV7aq60PP4ELASKAe0B0Z6VhsJ3OZTpMYYx9E9oMnOACRt3gjpNuiQUPUap1R13Y7w2zvOF8D2JW5HdVEybOMXkZuAm4FyItLPa1FhnLN5n4lILNAQmAeUVtXtnkU7gHS7HYjIQ8BD4JQoMCai7Vrp9NZp2MVpx69yjSX8QMpfHG4f4rT9/9AX1oX2r6zMLu5uAxYAtwIJXvMPAU/6egARKQiMB/qq6kHvCo+qqiKSbrciVR0CDAGnV4+vxzMmrKSkwNwBMO3fTlt+nQ5OtVlL+u6o1RYqNoeYIs7ztdOhwCVwaWgNG5ph4lfVxcBiERmtqhd0hp9KRKJxkv5oVf3WM3uniJRR1e0iUgbYlZ19GxP2kjbBd71h40yo2RZu+chJ+sZd+Ys7/6akwJR/wZ7VcPU/4Yq+EBUa3Y59aeNfLSLr0k5ZbSTOqf0wYKWqfuC1aCLQzfO4G3BhZSuNiQTHD8CgK52eJO0/gbtHOzcZmeCRKxd0mwS1b4UZb8DQ1rBzhdtR+STLG7hExPt+7xjgTqC4qr6cxXZXAH8AS4HUETpewGnn/xqoCGwEOqnqvsz2ld4NXMaEpZNHz57VJ34JlVqG3vi3kWjFRJj0pPOF3XsWlKrpdkRAxjdwZevOXc/OGudIZD6wxG8iwl8/ww+POzcQVbvO7WjMhTqyF5aMhWa9nbuojx90feSvbN+5KyKNvJ7mAuJ92c4Y46MTh5wyAQs/d8oEFCrjdkQmOwqUgOZ9nMd71sDQa6HlE9DiCYgKrpTpSzTvez0+DWwAOvklGmMizaa58O1DzoXcln3hmhfCqixwxMpX1Bnzd9q/YeUkZ7SvS2q5HdUZWSZ+Vb0mEIEYE5F2Lnf+7fETVGrubiwm5xQoCZ0+h2XfwuSnYfCVcO2Lzi+AIJDZDVxPAQdUdVia+fcDhVT1Qz/HZkx42rkc9m+EWjdDfE9ocDfkKeB2VMYf6t4OsVfA5Kfg4Da3ozkjszP+Ljg1dtL6AufGrg/9EZAxYSslGeb0h+lvQJEKUL2N0/ZrST+8FbwEOn3h/P3BKfq2eR40fwRyRbkSUmb9+HOr6qm0M1X1JCDprG+Mycj+jTCiHUx92Un49/8v6C74GT8SOfv3XjEBpr4Ew290bv5yQWaJP5eInFdHJ715xphMHNwGA1vCzmVw2yC4a5TTBmwi0w1vwu1DYc/fTpXV2R+f/TUQIJkl/v8DJovI1SJSyDO1AiYB7wUiOGNCWmr53sJl4ZrnnRt74jo7Z38mcolA/TvhkflQtTX870VY8nVgQ8jsBi5Phc7ngLqAAsuBt1X1p8CE57AbuEzIWTUZJj8D94wN6SqOxs9U4e+fnea/XFFO///ilXOs7T9bN3B5EnxAk7wxIe34QZjyPCwaBZfWsz75JnMiZ4fLPLYfht8AJao5d2+XqOq3w4bPIJLGuG3DLBjU0qmxc+XT8MD0oKnZYkJATFFnYJ1dK51rQnMHOhVA/cC6FRiTU9bNAMkFPX6Gik3djsaEGhHnGlCVq+GHJ+Dn55w7uzuNzHrbCz1Udoq0BZq18ZugtWOpM/B5peaQfApOn4C8Bd2OyoQ6VeeXY4GSzsDv2ZRRG78vg61/ISJFvJ5XEpFp2Y7EmHCxfAIMucZp01d1BuGwpG9ygogzzOZFJP3M+NLGPxOYJyI3i8iDwFTsrl0T6bYmwHcPQ9mG0GW8ddE0IcWXIm2DRWQ5MAPYAzRU1R1+j8yYYHVgK4y5x7kVv/MYpxyvMSHEl6ae+4DhQFdgBPCjiDTwc1zGBK+5A+DkEeg81u7ANSHJl149HYErVHUXMEZEvgNGAnH+DMyYoHXdaxB3D5Su7XYkxmRLlmf8qnqbJ+mnPp8PNPFrVMYEowWfwaEdTrGt0nXcjsaYbPNl6MUY4H6gDs5g66l6+isoY4LO4q9gUl/YvwGuf83taIy5KL706vkCuBS4AfgNKA8c8mdQxgSVTXNh4mMQ6xlFyZgQ50vir6aqLwFHVHUk0Baw2xJNZNi/Eb7qAkXKO0PpRUW7HZExF82XxJ86GEuSiNQFigCX+C8kY4LI/1507si952vIX9ztaIzJEb706hkiIsWAl4CJQEHgZb9GZUywuPVj2LsGSlZ3OxJjcowvvXqGqup+Vf1NVauo6iWqOiir7URkuIjsEpFlXvMaiMgcEVkqIj+ISOGLfQHG+MXScXDqOOQrCuXPK3ViTEjL8IxfRJ7KbENV/SCLfY8A+gOfe80bCjyjqr+JSE/gWZxfEsYEj4WfOxdz2/wHWjzqdjTG5LjMzvjfA+4FSuA07xRKM2VKVX8H9qWZXQP43fN4Ks7NYcYEj/V/wKQnnSHxmvZyOxpj/CKzNv6GQGecXjwJwBhgml5cHeflQHtgAnAnUCGjFUXkIeAhgIoVK17EIY3x0d618PV9ULwq3PmZc6OWMWEowzN+VV2sqs+pahwwDCdhrxCRWy/ieD2BPiKSgPOr4WQmxx+iqvGqGl+qVKmLOKQxPlB1qm0icM9XEFMky02MCVW+3LlbCufsvx6wBdiV+RYZU9VVQBvPfmvg/Jowxn0i0H4AHNsHxau4HY0xfpXZxd2eQCecMg3jgE7eNXuyQ0QuUdVdIpILeBHIsneQMX63djpUuQZK1XA7EmMCIrOLu0OBsjjlGW4AhorIxNQpqx2LyBhgDlBTRLaIyP1AZxH5G1gFbAM+u+hXYMzFmP8pfNEBln/rdiTGBExmTT3XXMyOVbVzBos+upj9GpNj1kyDn/4JNW6E2re5HY0xAZNh4lfV3wIZiDEBtfsv+KYHlKoFHYdCrii3IzImYHyp1WNMeEk+BV/dA7nzOD148mZ5W4oxYcU6KpvIExUNN77tdNksaveImMhjid9EDlXYuRwurQvVr3c7GmNck1l3zh+ADO/SVdWLuZHLmMCb8wlMfQl6/AwVbUgJE7kyO+N/L2BRGONvf/3s1NavfSuUv9ztaIxxlfXqMeFv53IYfz+UaQC3DYJc1qfBRDZfSjZUB94CauM12Lqq2n3tJvgdPwBf3u303Ok8BvLkdzsiY1zny8Xdz4BXgP/i3NTVA+sGakJF3sLQ9CGIvQIKl3U7GmOCgi8JPJ+qTgNEVTeq6qtYcTUT7FThwFan+FqLx6BsQ7cjMiZo+JL4T3iKqq0WkUdFpAPOwCzGBK8/3ocBzZ0a+8aYc/iS+J8A8gOPA42B+4Bu/gzKmIuy4nuY/jrUaGMllo1JR5Zt/Kr6p+fhYZz2fWOC17ZE+PZhp8vmrf2dph5jzDl86dUTD/wLqOS9vqrW92Ncxly4QzthTGfIXwLu/hKiY7LexpgI5EuvntHAs8BSIMW/4RhzEWKKOM07lz8ABS9xOxpjgpYviX+3qmY58IoxrklJgZOHIaYw3GLDPRiTFV8S/ysiMhSYBpxInamqNmSRCQ6/vQ3LxsP9UyF/cbejMSbo+ZL4ewC1gGjONvUoYInfuG/pOPjtHYi7F/IVczsaY0KCL4n/clWt6fdIjLlQm/+ECX2gUkto91/rwWOMj3zpxz9bRGr7PRJjLkTSZmcUrUKXQqcvnNG0jDE+8eWMvxmQKCLrcdr4BVDrzmlcFRUNpes4I2kVKOF2NMaEFF8S/41+j8IYX6WkgKY4Z/pdJ7gdjTEhKcOmHhEp7Hl4KIPJmMCb9hqMuQtOn8h6XWNMujI74/8SaAck4PTi8b5ypoAVQTGBtWg0zPoQ4ntClLXpG5NdmY3A1c7zb+Xs7FhEhuN8cexS1bqeeXHAIJwBXU4DfVR1fnb2byLMxtnwwxNQ+Wq46V3rwWPMRciyV4+ITPNlXjpGcP71gXeB11Q1DnjZ89yYzO1bD191gWKVoNNI58KuMSbbMjzjF5EYnHLMJUWkGGebegoD5bLasar+LiKxaWd7tgcoAmy70IBNBDpx0LmYe9eooLpJa/XOQ/SfsYaTp62ElfGfR66pRt1yRXJ0n5m18T8M9AXKAgu95h8E+mfzeH2BKSLyHs6vjRYZrSgiDwEPAVSsWDGbhzMhTdVp0inTAHrNCqpB0g8cO8X9Ixew/8hJyhS1KqDGf46dSs7xfWbWxv8R8JGIPKaqH+fQ8XoDT6rqeBHpBAwDrsvg+EOAIQDx8fGaQ8c3oeTn5yFXFLR5I6iSfkqK8vTXi9mWdIyxDzencaXg+RVijC98+TQNFZGnRORbERkvIn09zUDZ0Y2zNX6+AZpkcz8m3C0YDvMGnj3rDyKDf1/HLyt38q+2l1nSNyHJl8Q/EqgDfIzTxFMH+CKbx9sGXO15fC2wOpv7MeFs3a8w+Rmo3gbavO52NOeYs3Yv/zdlFW3rl6F7i1i3wzEmW3y5c7euqnrX6pkhIiuy2khExgCtcC4ObwFeAR7EaT7KDRzH04ZvzBl7VsPXXaFkDeg4zGnqCRI7Dx7nsTELqVyyAO90rI8E2S8RY3zlS+JfKCLNVHUugIg0BRZktZGqds5gUeMLiM9Emj1/Q55CcM9XzsAqQeJUcgqPfrmQIyeS+fLBZhTM68tHx5jg5Mv/3sY4FTo3eZ5XBP4SkaVYsTaT02q1haqtg2683Hd/XsWfG/bz0d1x1ChdyO1wjLko4V+kbecKKFHNyvYGM1X4+TkoEwdxnYMu6f+8bDuf/rGe+5pVon1clrewGBP0fEn8VXAu6AIsV9UZfownZ506Dp+3d+70bPE4NOoKefK7HZVJa94gZ2rZ1+1IzrN+zxGe/WYJDSoU5cV2l7kdjjE5IrPqnOVEZB7wKk7yrwK8KiLzRSQ0Tnty54UOA6FYLPz8T/iwHvzxPhw/4HZkJtXqqTDlBajVDlq/4nY05zh2MpneoxKIihI+uacheXMHz4VmYy5GZmf8/YGBqjrCe6aIdAUGAO39GFfOEIFq1znTxjlO0p/2byjXGKq0cjs6s2slfNPDGVClw+CguklLVXlxwjL+2nmIz7pfTvli9kvRhI/MEn9tVe2Qdqaqfi4i//JjTP5RqTlUGge7VkEpzxDC0/4NJ49Ci0ehSHl344tEa6Y5TW+dv4K8Bd2O5hxf/bmZ8Qu38Hjr6rSqeYnb4RiTozI7xUp3mYjkAkL3N+8ltc7eCXr8IPz5KXwUB98/CnvXuhpaxGnxKPSZG3Rfusu2HuCVicu5snpJnmhd3e1wjMlxmSX+SSLyqYgUSJ3heTwI+NHvkQVC2/fg8UXQuDss+Rr6x8P8T92OKrypwpR/wRbPrSD5i7sbTxoHjp6i16gEShTIw0d3NyQql92kZcJPZon/H8ABYKOIJIhIArABpzrnMwGILTCKVnS+APoudXr+xF7hzN+zGjbbGDE5btZHMKe/08wTZFJSlKe+TmTnweN80qURxQtYF2ATnjKrznkKeEZEXgKqeWavVdWjAYks0AqVhutfO/t85oeQOApir4Qrn3YuBtst+hdn1WT45VWo0wGuetbtaM4z8Le1TFu1i9durUOjilZ8zYSvLLtRqOoxVV3qmcIz6afnpnegzX+cM/8vboNPr4W/p7gdVejavgTGPwhlG8JtA4OqBw/ArDV7eP9/f3FLg7J0bV7J7XCM8avg+vQFk7wFnYuPfZdAuw/h2D7YMNNZpgrJp10NL+QsGAYxRaDzGIjO53Y059hx4DiPj1lElVIFefv2elZ8zYQ9qzSVldx5Ib4HNLwPkk8489ZMgx+fdu40jbvHWcdkru0HcOVWZwjFIJJafO3YqWTG3tuIAlZ8zUSAzMbcbZTZhqq6MLPlYScqtzOB0/c8X3GY1Bd+ewdaPOb0DMpTILM9RB5V+PVtaNwNCpd1LqQHmbd/WsWCjfvp17kh1S6x4msmMmR2evO+598YIB5YjDPgen2csszN/RtaEKvUAh6cDut/g9/fc0oOJI6BXn/YBWBvv/8f/PY25CsKzXq7Hc15fly6nWEz19OteSVubVDW7XCMCZjMevVcAyAi3wKNVHWp53ldnPo9kU3E6elTpZXT7fPIHmfe6ZMw60PnF0DBCL7jc9m3MOM/0KAzNO3ldjTnWbf7MP8Yt4S4CkX5V9vaWW9gTBjx5eJuzdSkD6CqywArU+itQhOodbPzePNc+PUtpyDc5GcgaVPm24ajrQkwoTdUaAa3fBR0v4KOnjxN71ELiY4SPunSiDy5rY+DiSy+/I9fIiJDRaSVZ/oUWOLvwEJW5avg0QVQvxMkjIB+DWFCHzhx2O3IAueX15xfO3ePDroL36rKi98t4+9dh/jo7oaUKxpcPYyMCQRfujD0AHoDT3ie/w4M9FtE4aBEVbj1Y7j6nzC7v3MGnHrh9/BuKFjK3fj87a4vnKavAiXdjuQ8X87fxLeLttL3uupcVSPM/w7GZCDLxK+qx0VkEPCjqv4VgJjCR5HycNPbkJLiNHcc2w8fN4IKTZ27gSuF0fXxlBSYP9i5thFTxJmCzJItSbw2cQVX1SjF49da8TUTubJs6hGRW4FE4GfP8zgRmejnuMJL6l2quaLhir6wbRF8diMMvwnW/OJ0ewx10193hk9cEZz/NZKOnqT3qIWUKpSXD++KI5cVXzMRzJc2/leAJkASgKomApX9F1IYy1vQOdPvuxRufAeSNsKojs6AJKFs8Vcw8wNo1M25thFkUlKUJ8cmsuuQFV8zBnxr4z+lqgfS3MYeBqeoLsqTH5r1gviesO5XKO3pTjjjTShWGerd4YwTHAo2zYOJjznF7Nq+H3Q9eAA+mbGGGX/t5vX2dYirUNTtcIxxnS9n/MtF5B4gSkSqi8jHwGw/xxUZcueBGm2cx8mnnCJwE3pBv0bOuACnjrsbX1ZSkmGiZ/SyTp8H5ZfVzNV7+OCXv2kfV5Z7m1nxNWPAt8T/GFAHOAF8iVOj/4lMtwBEZLiI7BKRZV7zxopIomfaICKJ2Yw7/ERFw0O/wj1fO/VsfnzGuRdg3a9uR5axXFFw9xgn5iAbUAVg+4FjPP7VIqqVKshbVnzNmDN8SfxtVfVfqnq5Z3oRuNWH7UYAN3rPUNW7VDVOVeOA8cC3FxrwhdJQunAqAjVugPv/B90mQZn6ULyqs2zvWji6z934UqUkw7LxzkXpktWgZPD1kDl5OoVHRi/kxKlkBt7bmPx5rPiaMal8SfzP+zjvHKr6O5BuphLn1KsTMMaH42fbNws203vUQo6dTPbnYXKeCFS+Eu4dD0UrOPMmPw3/resMW3hoh7vxTX0ZxvUM6l8jb/20koWbknjnjvpUuyS4BnI3xm0ZJn4RucnTnl9ORPp5TSOAiy1GfyWwU1VXZ3L8h0RkgYgs2L17d7YOcvjEaaas2MHdn85lz+ET2Y01ONzwJtRqC3MHOE1Ak56E/RsCH0fCSGfoxCYPQ9VrAn98H0xaso3PZm2ge4tY2tW34mvGpJXZGf82nCqcx4EEr2kicMNFHrczWZztq+oQVY1X1fhSpbJ3h2WPlpUZ2KUxf+04SIcBs1izK4TLJpSuDR0/hccSIK4LLBrlNLcE0vo/YPJTUPVa54soCK3ZdZh/jltCo4pFeeFmKyllTHokqzZwEYn2jL974TsXiQUmqWpdr3m5ga1AY1Xd4st+4uPjdcGCBdkJAYBFm/bzwMgFnEpOYUjXeJpVKZHtfQWNg9ud+wLyFoKl42D5d849AuUyHUYh+04egY8aQL5icP9Up9RykDl68jS3fTKLPYdPMvnxKyhTxOrwmMgmIgmqGp92vi9t/LEiMk5EVojIutTpImK5Dljla9LPCQ0rFuO7Pi0pVSgv9w2bx3eLAnZo/ylcxkn6ACcOwYY/4NNr4IsOzhCROX1RO08B6DAY7hkblElfVXnh26Ws3nWYj+6Os6RvTCZ8Sfyf4RRlOw1cA3wOjMpqIxEZA8wBaorIFhG537Pobvx8UTc9FUvk59veLWlcqRhPjl1Mv2mrQ6vHT2bie0DfZXDda7BjGYxo61QEzQnJp2HjHOdxtdZQvErO7DeHjZq3iQmJ23jyuhpcWd2KrxmTGV+aehJUtbGILFXVet7zAhIhF9/U4+3E6WSeG7+U7xZt5Y7G5XmzQ73wqsd+6pjT/l+oDFzWzikHvWYqXHar0+/+Qk1+Bv4cCn3mwCXB2Wa+eHMSdw6aQ4tqJRje7XKrw2OMR0ZNPb50bj4hIrmA1SLyKE77fMj2j8ubO4oPOjWgQvH89Ju2mm1Jxxh4b2OK5Au+u06zJTofNHnw7POlXzs9gIpXhSuehPp3OXcM+2L+p/Dnp9Di8aBN+vuPnKTPaCu+ZsyF8OVU9wkgP/A40Bi4D+jmz6D8TUR46voavHdnA+av38cdA2ezZf9Rt8Pyj0bd4M6RThv9xEedgWHmDXbKKGdm7XT46Z9Q82a47tWAhHqhUlKUvmMT2X3oBAPvbUTR/FZ8zRhfZNnUEwxysqknrdlr9vDwqARioqMY1i2e+uWL+uU4rlN1SkD//p5THqL7JGd+8qnza+wc2gH9mzg3j/X8+exF5CDz0S+r+e8vf/PGbXWtDo8x6cioqSfDxC8iP5BJFU5V9aVsQ47wZ+IHWL3zEN0/+5N9R07Sr3NDrq9d2m/HCgonDjnJ/OB2GHwVNO4GTXtDAU83V1WnXb/GDVC0oruxZuD3v3fT7bP53BZXjg86NbA6PMakIzuJ/+rMdqiqv+VQbFnyd+IH2HXoOA+MXMDSrQd4pV1tureMgCEH9m9wyi+smOhcG4i7B+rcDrEt3Y4sU9uSjtG23x+UKpSXCY+0tDo8xmTgghN/MAlE4gfnBqDHxyTyy8qd9GxZmX+1vYyoSLhYuPsvmPkhLP4SovPDE4udwdKD0MnTKXQaPIc1uw7z/aMtqVoqZPsZGON32e7VIyLrSafJR1WDs0P3RcifJzeD72vMG5NXMHzWerbsP8pHdzckX55sdIMMJaVqQoeB0Oo5SNoUtEkf4M0fV5K4OYkBXRpZ0jcmm3z5jez9bRED3AkEX/H1HBKVS3jlljpUKJaf1yev4O4hcxja7XJKFcrrdmj+V6ySMwWpiYu3MWL2Bnq2rMzN9cq4HY4xISvL7pyqutdr2qqqHwJt/R+au3peUZnB9zbmr52H6DBgFqt3HnI7pIi2Ztchnhu/hMaVivH8zbXcDseYkJZl4heRRl5TvIj0wrdfCiGvTZ1LGftQc46fSuH2gbOZvXaP2yFFpCMnTtNr1ELyRUfxyT2NiI4KozutjXGBL5+g972mt4BGOIOoRIQGFYryXZ8WlC4cQ7fh8xmfEAYF3kKIqvL8t0tZt/sw/To35NIiMW6HZEzIy/LMXVWDc7SNAKpQPD/je7eg96gEnv5mMZv2HaXvddWt73gAfDF3IxMXb+PZG2rSslpJt8MxJiz40tTzpogU9XpeTETe8GtUQahIvmhG9GhCx0bl+Wjaap7+ejEnT2dR9sBclEWb9vP6pBW0rnUJva+u6nY4xoQNX5p6blLVpNQnqrofuNlvEQWxPLlz8d6d9Xnq+hp8u2gr3YbP58DRbI1RY7Kw78hJHhm9kNKFY/igkxVfMyYn+ZL4o0TkTF9GEckHREDfxvSJCI+3rs4HnRqwYOM+Og6azeZ9YVrgzSXJKcoTXy1iz+GTDOzSmCL5w6RyqjFBwpfEPxqYJiL3ewZTmQqM9G9Ywe/2RuX5vGdTdh08TocBs0jcnOR2SGGj37TV/LF6D6/eWod65Yu4HY4xYceXfvzvAP8BLvNMr6vqu/4OLBQ0r1qCb/u0ICY6iruHzGHK8h1uhxTyfv1rF/2mr+b2RuXo3KSC2+EYE5asVk8O2H3oBA98voAlW5J4sW1t7r8iAgq8+cFWT/G1SwvH8F2fluFfKsMYP7vgwdZF5JCIHExnOiQiB/0bbmgpVSgvXz3YjDa1S/P6pBW8OnE5ySnB/4UaTE6cTqbP6IWcTlYGdGlkSd8YP8qwH7+qBufoG0EqX54oBnRpzJs/rmTYTKfAW7/ODa1ksI/+M3klizcnMejeRlSx4mvG+JXP976LyCUiUjF18mdQoSoql/BSu9r8u30dpq/axV2D57Lr0HG3wwp63ydu5fM5G3ngisrcWNeKrxnjb77cwHWriKwG1gO/ARuAn/wcV0jr2jyWT7vGs2bXYTp8Mpu/rcBbhlbvPMRz45dyeWwx/nmTFV8zJhB8OeN/HWgG/K2qlYHWwFy/RhUGWl9Wmq8fbs7J5BQ6DpjNrDVW4C2twydO02tUAgXyRtHfiq8ZEzC+fNJOqepeIJeI5FLVGZxbo99koF75Ikx4pCVlijoF3r5ZsNntkIKGqvLc+CWs33OEfp0bUrqwFV8zJlB8SfxJIlIQ+B0YLSIfAUey2khEhovILhFZlmb+YyKySkSWi0jY3w9Qrmg+xvVuQbMqJXh23BI++N9fhEIXWn8bOXsDk5Zs55kbatKiqhVfMyaQfEn87YGjwJPAz8Ba4BYfthsB3Og9Q0Su8eyvgarWAd67kGBDVeGYaD7rcTmd4svTb/oanvp6MSdOJ7sdlmsSNu7njckrue6yS+h1lRVfMybQMuxrKCLVgNKqOsszKwUYKSJXAEWBvZntWFV/F5HYNLN7A2+r6gnPOruyGXfIiY7KxTsd61OxeH7e+9/fbE06xpD7GlM0fx63QwuovYdP8OiXCylTNIb377Tia8a4IbMz/g+B9G7UOuBZlh01gCtFZJ6I/CYil2e0oog8JCILRGTB7t27s3m44CIiPHptdT66O47ETUncPnA2m/ZGToE3p/haInuPWPE1Y9yUWeIvrapL0870zIvN5vFy4wzU3gx4FvhaMhjNRFWHqGq8qsaXKlUqm4cLTu3jyvHF/U3Ye/gkHQbMYtGm/W6HFBAf/fI3M9fs4d+31qFuOSu+ZoxbMkv8RTNZli+bx9sCfKuO+TjNRxF5Za9pFafAW4G8ubl7yFx+Wrrd7ZD8asZfu+g3fQ13NC7PXZdb8TVj3JRZ4l8gIg+mnSkiDwAJ2TzeBOAaz35qAHmAiO3gXrVUQb7r04LaZQvT58uFDP1jXVj2+Nmy/yhPjk2k1qWFeL19XRuy0hiXZVZIpi/wnYh04Wyij8dJ1h2y2rGIjAFaASVFZAvwCjAcGO7p4nkS6KbhmOkuQImCeRnzYDOeHJvIG5NXsnHvUV65pTa5w+RmptTia8nJyqB7G1vxNWOCQGZF2nYCLTxdMOt6Zk9W1em+7FhVO2ew6N4LCzH8xURH8ck9jXjn51UM/n0dW5OO8XHnhhTIG/oF3l6ftIIlWw4w6N7GxJYs4HY4xhgyP+MHwHOn7owAxBLRcuUSnr/5MsoXz88r3y+j0+A5DO9+eUjf0Tph0VZGzd3EQ1dV4ca6l7odjjHGIzzaE8LIfc0qMazb5azfc4QOn8xi1Y7QHPrg752HeP7bpTSJLc4/bqjpdjjGGC+W+IPQNbUu4euHm3M6Rblj4Bz+WB1a9zGcLb6Wm/73NAyb6xXGhAv7RAapuuWcAm/li+Wjx2d/MvbPTW6H5BNV5Z/jlrBx71H639OQS0K4qcqYcGWJP4iVLZqPb3o1p3nVEvxz/FLemxL8Bd6Gz9rA5KXbefaGmjSrUsLtcIwx6bDEH+QKxUQzvPvl3H15BfrPWMMTXyUGbYG3BRv28daPK7m+dmkevqqK2+EYYzIQ+v0FI0B0VC7eur0eFUvk592f/2LHgeMMvq8xxQoET4G3PYdP8MiXCylXLB/v3dnAbtIyJojZGX+IEBH6tKrGx50bkrjZKfC2cW+WwyIEhFN8bRFJR08xoEsjiuSz4mvGBDNL/CHmlgZlGf1gU/YfPUmHAbNJ2Oh+gbf/Tv2bWWv28nr7utQpa8XXjAl2lvhD0OWxxfmuT0sKx+Sm86dzmbzEvQJv01ftpP+MNXSKL08nK75mTEiwxB+iKpcswLd9WlKvXBEe+XIhg39bG/AeP5v3HeXJsYupXaYw/25fN+sNjDFBwRJ/CCteIA+jH2hK2/pleOunVbw4YRmnk1MCcuzjp5ziaymqDLy3ETHRVnzNmFBhvXpCXEx0FB/f3ZAKxfIz6Le1bE06Rv97GlHQzwXe/j1pBUu3HmDIfY2pVMKKrxkTSuyMPwzkyiU8d1Mt3uxQjz9W76HToDnsOHDcb8f7duEWvpy3iV5XV6VNHSu+ZkyoscQfRu5pWpFh3eLZuPcIt30yixXbcr7A26odB3nhu6U0q1KcZ9rUyPH9G2P8zxJ/mGlV8xK+6dUCgDsHzea3v3OuwNuh46foPWohhWOi6dfZiq8ZE6rskxuGapctzHePtKBiiQL0HPEnX867+AJvqsqz3yxh076j9L+nEZcUsuJrxoQqS/xhqkwRp8DbFdVK8sJ3S3nn51WkpGS/u+ewmev5efkO/nljTZpULp6DkRpjAs0SfxgrmDc3w7rFc0/Tigz8dS2Pf7WI46cuvMDbnxv28dZPq7ihTmkevNKKrxkT6qw7Z5jLHZWL/9xWl0rF8/PWT6vYceA4Q7rGU9zHAm+7D53gkdELqVAsH/9nxdeMCQt2xh8BRISHr67KJ/c0YsnWA9w+YBbr92Rd4O10cgqPj1nEgWOnGNClMYVjrPiaMeHAEn8EaVu/DGMebMqBY6e4fcAsFmzYl+n6H0z9mznr9vLGbXWpXbZwgKI0xvibJf4I07iSU+CtaP483DN0Hj8s3pbuer+s2MmAX9dy9+UVuDPeiq8ZE04s8Ueg2JIF+LZ3CxqUL8JjYxYx8NdzC7xt2nuUp75OpE7Zwrx6ax0XIzXG+IPfEr+IDBeRXSKyzGveqyKyVUQSPdPN/jq+yVyxAnn44v6m3NKgLO/8vIoXvlvKqeQUp/jalwkADOzS2IqvGROG/NmrZwTQH/g8zfz/qup7fjyu8VFMdBQf3RVHxeL5+GTGWrYmHadUwbws23qQoV3jqVgiv9shGmP8wG+JX1V/F5FYf+3f5IxcuYRnb6hFhWL5+deEZSSnKH1aVeW62qXdDs0Y4ydu9ON/VES6AguAp1U13bEDReQh4CGAihUrBjC8yHR3k4pULJ6f2Wv30ve66m6HY4zxI/HnqE2eM/5JqlrX87w0sAdQ4HWgjKr2zGo/8fHxumDBAr/FaYwx4UhEElQ1Pu38gPbqUdWdqpqsqinAp0CTQB7fGGNMgBO/iJTxetoBWJbRusYYY/zDb238IjIGaAWUFJEtwCtAKxGJw2nq2QA87K/jG2OMSZ8/e/V0Tmf2MH8dzxhjjG/szl1jjIkwlviNMSbCWOI3xpgIY4nfGGMijF9v4MopIrIb2JjNzUvi3DQWbCyuC2NxXRiL68IEa1xwcbFVUtVSaWeGROK/GCKyIL0719xmcV0Yi+vCWFwXJljjAv/EZk09xhgTYSzxG2NMhImExD/E7QAyYHFdGIvrwlhcFyZY4wI/xBb2bfzGGGPOFQln/MYYY7xY4jfGmAgTNolfRG4Ukb9EZI2IPJfO8rwiMtazfF6ghoX0Ia7uIrLbawD6BwIQ03AR2SUi6ZbFFkc/T8xLRKSRv2PyMa5WInLA6716OUBxVRCRGSKyQkSWi8gT6awT8PfMx7gC/p6JSIyIzBeRxZ64XktnnYB/Hn2MK+CfR69jR4nIIhGZlM6ynH2/VDXkJyAKWAtUAfIAi4HaadbpAwzyPL4bGBskcXUH+gf4/boKaAQsy2D5zcBPgADNgHlBElcrnBHdAv3/qwzQyPO4EPB3On/HgL9nPsYV8PfM8x4U9DyOBuYBzdKs48bn0Ze4Av559Dr2U8CX6f29cvr9Cpcz/ibAGlVdp6onga+A9mnWaQ+M9DweB7QWEQmCuAJOVX8H9mWySnvgc3XMBYqmGUTHrbhcoarbVXWh5/EhYCVQLs1qAX/PfIwr4DzvwWHP02jPlLYXScA/jz7G5QoRKQ+0BYZmsEqOvl/hkvjLAZu9nm/h/A/AmXVU9TRwACgRBHEBdPQ0D4wTkQp+jskXvsbthuaen+o/iUidQB/c8xO7Ic7ZojdX37NM4gIX3jNPs0UisAuYqqoZvl8B/Dz6Ehe483n8EPgHkJLB8hx9v8Il8YeyH4BYVa0PTOXst7o530Kc2iMNgI+BCYE8uIgUBMYDfVX1YCCPnZks4nLlPVNnbO04oDzQRETqBuK4WfEhroB/HkWkHbBLVRP8faxU4ZL4twLe38zlPfPSXUdEcgNFgL1ux6Wqe1X1hOfpUKCxn2PyhS/vZ8Cp6sHUn+qq+iMQLSIlA3FsEYnGSa6jVfXbdFZx5T3LKi433zPPMZOAGcCNaRa58XnMMi6XPo8tgVtFZANOc/C1IjIqzTo5+n6FS+L/E6guIpVFJA/OxY+JadaZCHTzPL4DmK6eKyVuxpWmHfhWnHZat00Eunp6qjQDDqjqdreDEpFLU9s1RaQJzv9fvycLzzGHAStV9YMMVgv4e+ZLXG68ZyJSSkSKeh7nA64HVqVZLeCfR1/icuPzqKrPq2p5VY3FyRHTVfXeNKvl6PvltzF3A0lVT4vIo8AUnJ40w1V1uYj8G1igqhNxPiBfiMganAuIdwdJXI+LyK3AaU9c3f0dl4iMwentUVJEtgCv4FzoQlUHAT/i9FJZAxwFevg7Jh/jugPoLSKngWPA3QH48gbnjOw+YKmnfRjgBaCiV2xuvGe+xOXGe1YGGCkiUThfNF+r6iS3P48+xhXwz2NG/Pl+WckGY4yJMOHS1GOMMcZHlviNMSbCWOI3xpgIY4nfGGMijCV+Y4yJMJb4TUgRkWRP1cRlIvJDar/sHNhvdxHpnxP7SrPf3CLypois9qr4+K8c3P8IEbkjp/ZnIoMlfhNqjqlqnKrWxenP/IjbAWXhDaAsUM9TKuBKPPcmePPc+GWfRxMQ9h/NhLI5eAqhiUgTEZkjTj3z2SJS0zO/u4h8KyI/e866303dWER6iMjfIjIf52ao1PmxIjLdU6hrmohU9MwfISIDRWSuiKwTp9b9cBFZKSIj0gYnIvmBB4HHVPU4OFU0VfVVr+P8JSKfA8uACp79L5A09eJFZIOIvCsiS8WpKV/N61BXeV7zOjv7N76wxG9Ckufuy9acLYGxCrhSVRsCLwNveq0eB9wF1APuEmcAkzLAazgJ/wqgttf6HwMjPYW6RgP9vJYVA5oDT3qO/V+gDlBPROLShFkN2OQpmZyR6sAAVa2jqhuBf6lqPFAfuFpE6nute0BV6wH9cao5pirjeQ3tgLczOZYxgCV+E3ryecoT7ABK41RQBKdo1TfijN6VmoxTTVPVA56z7hVAJaAp8Kuq7vaMlTDWa/3mOANiAHyBk1RT/eApebAU2KmqS1U1BVgOxGYWuOcXRqKIbJaz5X43eur3p+okIguBRZ7X4P2FNMbr3+Ze8yeoaoqqrvC8J8ZkyhK/CTXHPG3llXBGVEpt438dmOFp+78FiPHa5oTX42QurkZV6r5S0uw3JZ39rgEqikghAFX9zBP7AZzaTQBHUlcWkcrAM0Brz6+NyWleh2bw2DsOfw8uZMKAJX4TklT1KPA48LScLVObWga5uw+7mIfTlFJCnNLGd3otm83ZIlhdgD8uIsZhQH8RiYEzTVR5MtikMM4XwQERKQ3clGb5XV7/zslOTMZAmFTnNJFJVReJyBKgM/AuTuXFF3HOlLPadruIvIqTQJOARK/FjwGficizwG4urtLmv3B+jSwTkUM4FTJHAttwevt4x7RYRBbhXK/YDMxKs69intd7Auc1G5MtVp3TmBAgziAd8aq6x+1YTOizph5jjIkwdsZvjDERxs74jTEmwljiN8aYCGOJ3xhjIowlfmOMiTCW+I0xJsL8P9+jczLRXmOgAAAAAElFTkSuQmCC\n", "image/png": "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\n",
"text/plain": [ "text/plain": [
"<Figure size 432x288 with 1 Axes>" "<Figure size 432x288 with 1 Axes>"
] ]
...@@ -698,6 +699,9 @@ ...@@ -698,6 +699,9 @@
], ],
"metadata": { "metadata": {
"celltoolbar": "Raw Cell Format", "celltoolbar": "Raw Cell Format",
"interpreter": {
"hash": "3b61f83e8397e1c9fcea57a3d9915794102e67724879b24295f8014f41a14d85"
},
"kernelspec": { "kernelspec": {
"display_name": "Python 3", "display_name": "Python 3",
"language": "python", "language": "python",
...@@ -713,7 +717,7 @@ ...@@ -713,7 +717,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.7.10" "version": "3.7.11"
}, },
"toc": { "toc": {
"base_numbering": 1, "base_numbering": 1,
......
...@@ -136,7 +136,7 @@ ...@@ -136,7 +136,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 2, "execution_count": 4,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:11:08.078417Z", "end_time": "2021-04-30T09:11:08.078417Z",
...@@ -153,7 +153,10 @@ ...@@ -153,7 +153,10 @@
"# 加载额外需要用到的包\n", "# 加载额外需要用到的包\n",
"import numpy as np\n", "import numpy as np\n",
"import matplotlib.pyplot as plt\n", "import matplotlib.pyplot as plt\n",
"import networkx as nx" "import networkx as nx\n",
"\n",
"import warnings\n",
"warnings.filterwarnings(\"ignore\")"
] ]
}, },
{ {
...@@ -165,7 +168,7 @@ ...@@ -165,7 +168,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 3, "execution_count": 5,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:11:08.411878Z", "end_time": "2021-04-30T09:11:08.411878Z",
...@@ -175,7 +178,7 @@ ...@@ -175,7 +178,7 @@
"outputs": [ "outputs": [
{ {
"data": { "data": {
"image/png": "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\n", "image/png": "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\n",
"text/plain": [ "text/plain": [
"<Figure size 432x288 with 1 Axes>" "<Figure size 432x288 with 1 Axes>"
] ]
...@@ -190,7 +193,7 @@ ...@@ -190,7 +193,7 @@
"G = nx.Graph()\n", "G = nx.Graph()\n",
"V = range(n)\n", "V = range(n)\n",
"G.add_nodes_from(V)\n", "G.add_nodes_from(V)\n",
"E = [(0, 1), (1, 2), (2, 3), (3, 0)]\n", "E = [(0, 1), (1, 2), (2, 3), (3, 0), (1, 3)]\n",
"G.add_edges_from(E)\n", "G.add_edges_from(E)\n",
"\n", "\n",
"# 将生成的图 G 打印出来\n", "# 将生成的图 G 打印出来\n",
...@@ -221,7 +224,7 @@ ...@@ -221,7 +224,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 4, "execution_count": 6,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:11:08.426170Z", "end_time": "2021-04-30T09:11:08.426170Z",
...@@ -233,7 +236,7 @@ ...@@ -233,7 +236,7 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"[[-1.0, 'z0,z1'], [-1.0, 'z1,z2'], [-1.0, 'z2,z3'], [-1.0, 'z3,z0']]\n" "[[-1.0, 'z0,z1'], [-1.0, 'z1,z2'], [-1.0, 'z2,z3'], [-1.0, 'z3,z0'], [-1.0, 'z1,z3']]\n"
] ]
} }
], ],
...@@ -261,7 +264,7 @@ ...@@ -261,7 +264,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 5, "execution_count": 7,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:11:08.792299Z", "end_time": "2021-04-30T09:11:08.792299Z",
...@@ -273,8 +276,8 @@ ...@@ -273,8 +276,8 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"[-4. 0. 0. 0. 0. 4. 0. 0. 0. 0. 4. 0. 0. 0. 0. -4.]\n", "[-5. 1. -1. 1. 1. 3. 1. -1. -1. 1. 3. 1. 1. -1. 1. -5.]\n",
"H_max: 4.0\n" "H_max: 3.0\n"
] ]
} }
], ],
...@@ -319,7 +322,7 @@ ...@@ -319,7 +322,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 6, "execution_count": 8,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:11:10.245237Z", "end_time": "2021-04-30T09:11:10.245237Z",
...@@ -373,7 +376,7 @@ ...@@ -373,7 +376,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 7, "execution_count": 9,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:11:11.218109Z", "end_time": "2021-04-30T09:11:11.218109Z",
...@@ -419,7 +422,7 @@ ...@@ -419,7 +422,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 8, "execution_count": 10,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:11:12.968989Z", "end_time": "2021-04-30T09:11:12.968989Z",
...@@ -443,7 +446,7 @@ ...@@ -443,7 +446,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 9, "execution_count": 11,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:11:54.550338Z", "end_time": "2021-04-30T09:11:54.550338Z",
...@@ -455,32 +458,32 @@ ...@@ -455,32 +458,32 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"iter: 10 loss: -3.8886\n", "iter: 10 loss: -1.8359\n",
"iter: 20 loss: -3.9134\n", "iter: 20 loss: -2.5392\n",
"iter: 30 loss: -3.9659\n", "iter: 30 loss: -2.7250\n",
"iter: 40 loss: -3.9906\n", "iter: 40 loss: -2.8061\n",
"iter: 50 loss: -3.9979\n", "iter: 50 loss: -2.8748\n",
"iter: 60 loss: -3.9993\n", "iter: 60 loss: -2.9134\n",
"iter: 70 loss: -3.9998\n", "iter: 70 loss: -2.9302\n",
"iter: 80 loss: -3.9999\n", "iter: 80 loss: -2.9321\n",
"iter: 90 loss: -4.0000\n", "iter: 90 loss: -2.9321\n",
"iter: 100 loss: -4.0000\n", "iter: 100 loss: -2.9325\n",
"iter: 110 loss: -4.0000\n", "iter: 110 loss: -2.9327\n",
"iter: 120 loss: -4.0000\n", "iter: 120 loss: -2.9328\n",
"\n", "\n",
"训练后的电路:\n", "训练后的电路:\n",
"--H----*-----------------*--------------------------------------------------X----Rz(3.140)----X----Rx(0.824)----*-----------------*--------------------------------------------------X----Rz(0.737)----X----Rx(2.506)----*-----------------*--------------------------------------------------X----Rz(4.999)----X----Rx(4.854)----*-----------------*--------------------------------------------------X----Rz(0.465)----X----Rx(1.900)--\n", "--H----*-----------------*--------------------------------------------------x----Rz(2.379)----x----Rx(2.503)-----------------------------------*-----------------*--------------------------------------------------x----Rz(1.230)----x----Rx(0.792)-----------------------------------*-----------------*--------------------------------------------------x----Rz(4.375)----x----Rx(5.180)-----------------------------------*-----------------*--------------------------------------------------x----Rz(0.711)----x----Rx(2.353)---------------------------------\n",
" | | | | | | | | | | | | | | | | \n", " | | | | | | | | | | | | | | | | \n",
"--H----X----Rz(3.140)----X----*-----------------*---------------------------|-----------------|----Rx(0.824)----X----Rz(0.737)----X----*-----------------*---------------------------|-----------------|----Rx(2.506)----X----Rz(4.999)----X----*-----------------*---------------------------|-----------------|----Rx(4.854)----X----Rz(0.465)----X----*-----------------*---------------------------|-----------------|----Rx(1.900)--\n", "--H----x----Rz(2.379)----x----*-----------------*---------------------------|-----------------|--------*---------------------*----Rx(2.503)----x----Rz(1.230)----x----*-----------------*---------------------------|-----------------|--------*---------------------*----Rx(0.792)----x----Rz(4.375)----x----*-----------------*---------------------------|-----------------|--------*---------------------*----Rx(5.180)----x----Rz(0.711)----x----*-----------------*---------------------------|-----------------|--------*---------------------*----Rx(2.353)--\n",
" | | | | | | | | | | | | | | | | \n", " | | | | | | | | | | | | | | | | | | | | | | | | \n",
"--H---------------------------X----Rz(3.140)----X----*-----------------*----|-----------------|----Rx(0.824)---------------------------X----Rz(0.737)----X----*-----------------*----|-----------------|----Rx(2.506)---------------------------X----Rz(4.999)----X----*-----------------*----|-----------------|----Rx(4.854)---------------------------X----Rz(0.465)----X----*-----------------*----|-----------------|----Rx(1.900)--\n", "--H---------------------------x----Rz(2.379)----x----*-----------------*----|-----------------|--------|---------------------|----Rx(2.503)---------------------------x----Rz(1.230)----x----*-----------------*----|-----------------|--------|---------------------|----Rx(0.792)---------------------------x----Rz(4.375)----x----*-----------------*----|-----------------|--------|---------------------|----Rx(5.180)---------------------------x----Rz(0.711)----x----*-----------------*----|-----------------|--------|---------------------|----Rx(2.353)--\n",
" | | | | | | | | | | | | | | | | \n", " | | | | | | | | | | | | | | | | | | | | | | | | \n",
"--H--------------------------------------------------X----Rz(3.140)----X----*-----------------*----Rx(0.824)--------------------------------------------------X----Rz(0.737)----X----*-----------------*----Rx(2.506)--------------------------------------------------X----Rz(4.999)----X----*-----------------*----Rx(4.854)--------------------------------------------------X----Rz(0.465)----X----*-----------------*----Rx(1.900)--\n", "--H--------------------------------------------------x----Rz(2.379)----x----*-----------------*--------x--------Rz(2.379)----x----Rx(2.503)--------------------------------------------------x----Rz(1.230)----x----*-----------------*--------x--------Rz(1.230)----x----Rx(0.792)--------------------------------------------------x----Rz(4.375)----x----*-----------------*--------x--------Rz(4.375)----x----Rx(5.180)--------------------------------------------------x----Rz(0.711)----x----*-----------------*--------x--------Rz(0.711)----x----Rx(2.353)--\n",
" \n", " \n",
"优化后的参数 gamma:\n", "优化后的参数 gamma:\n",
" [3.14046713 0.73681226 4.99897226 0.46481489]\n", " [2.37918879 1.22914743 4.37582352 0.71142941]\n",
"优化后的参数 beta:\n", "优化后的参数 beta:\n",
" [0.82379898 2.50618308 4.85422542 1.90024859]\n" " [2.50287593 0.79179726 5.17941547 2.35294027]\n"
] ]
} }
], ],
...@@ -529,7 +532,7 @@ ...@@ -529,7 +532,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 10, "execution_count": 20,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:11:55.548009Z", "end_time": "2021-04-30T09:11:55.548009Z",
...@@ -539,7 +542,7 @@ ...@@ -539,7 +542,7 @@
"outputs": [ "outputs": [
{ {
"data": { "data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYIAAAEWCAYAAABrDZDcAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Z1A+gAAAACXBIWXMAAAsTAAALEwEAmpwYAAAbM0lEQVR4nO3de9hcZX3u8e+dcBRQQRAtCYbWUMUDqAHZtdsDgg1bDVBROSkqNraSCpe2CluLgnZv1MqubAI1ioh2S/BsqhGwKnZrt5iAKASMpAgSFI0iB2UDRu7+sVZgmMw775r3XWtm8q77c11zZdbpt34TwvxmPetZzyPbREREe80adQIRETFaKQQRES2XQhAR0XIpBBERLZdCEBHRcikEEREtt9WoExjUrrvu6nnz5o06jYiILcqVV175S9u79dq2xRWCefPmsXr16lGnERGxRZF080Tb0jQUEdFyKQQRES2XQhAR0XIpBBERLZdCEBHRcikEEREtl0IQEdFyKQQRES23xT1QFlu2ead8ecrH3nTmi2vMJCI2yRVBRETLpRBERLRco4VA0kJJayWtk3RKj+2vkbRB0tXl6/VN5hMREZtr7B6BpNnAUuAQYD2wStIK29d17Xqx7SVN5REREf01eUVwALDO9o227weWA4c1eL6IiJiCJgvBHsAtHcvry3XdXibpB5I+I2lur0CSFktaLWn1hg0bmsg1IqK1Rn2z+F+AebafDnwVuLDXTraX2V5ge8Fuu/WcVyEiIqaoyUJwK9D5C39Oue5Btn9l+75y8SPAsxrMJyIiemiyEKwC5kvaS9I2wFHAis4dJD2+Y3ERcH2D+URERA+N9RqyvVHSEuBSYDbwUdtrJJ0BrLa9AniTpEXARuB24DVN5RMREb01OsSE7ZXAyq51p3W8PxU4tckcIiKiv1HfLI6IiBHLoHMRLZJB/6KXXBFERLRcCkFERMulEEREtFwKQUREy6UQRES0XApBRETLpRBERLRcCkFERMulEEREtFwKQUREy6UQRES0XApBRETLpRBERLRcCkFERMulEEREtFwKQUREy6UQRES0XApBRETLpRBERLRcCkFERMulEEREtFwKQUREy6UQRES0XApBRETLpRBERLRcCkFERMulEEREtFwKQUREy6UQRES03KSFQNJzJO1Qvj9O0lmSnlAluKSFktZKWifplD77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\n", "image/png": "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\n",
"text/plain": [ "text/plain": [
"<Figure size 432x288 with 1 Axes>" "<Figure size 432x288 with 1 Axes>"
] ]
...@@ -569,7 +572,7 @@ ...@@ -569,7 +572,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 11, "execution_count": 21,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:11:55.906817Z", "end_time": "2021-04-30T09:11:55.906817Z",
...@@ -586,7 +589,7 @@ ...@@ -586,7 +589,7 @@
}, },
{ {
"data": { "data": {
"image/png": "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\n", "image/png": "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\n",
"text/plain": [ "text/plain": [
"<Figure size 432x288 with 1 Axes>" "<Figure size 432x288 with 1 Axes>"
] ]
...@@ -603,10 +606,15 @@ ...@@ -603,10 +606,15 @@
"# 在图上画出上面得到的比特串对应的割\n", "# 在图上画出上面得到的比特串对应的割\n",
"node_cut = [\"blue\" if cut_bitstring[v] == \"1\" else \"red\" for v in V]\n", "node_cut = [\"blue\" if cut_bitstring[v] == \"1\" else \"red\" for v in V]\n",
"\n", "\n",
"edge_cut = [\n", "edge_cut = []\n",
" \"solid\" if cut_bitstring[u] == cut_bitstring[v] else \"dashed\"\n", "for u in range(n):\n",
" for (u, v) in E\n", " for v in range(u+1,n):\n",
" ]\n", " if (u, v) in E or (v, u) in E:\n",
" if cut_bitstring[u] == cut_bitstring[v]:\n",
" edge_cut.append(\"solid\")\n",
" else:\n",
" edge_cut.append(\"dashed\")\n",
"\n",
"nx.draw(\n", "nx.draw(\n",
" G,\n", " G,\n",
" pos,\n", " pos,\n",
...@@ -640,6 +648,9 @@ ...@@ -640,6 +648,9 @@
} }
], ],
"metadata": { "metadata": {
"interpreter": {
"hash": "3b61f83e8397e1c9fcea57a3d9915794102e67724879b24295f8014f41a14d85"
},
"kernelspec": { "kernelspec": {
"display_name": "Python 3", "display_name": "Python 3",
"language": "python", "language": "python",
...@@ -655,7 +666,7 @@ ...@@ -655,7 +666,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.7.10" "version": "3.7.11"
}, },
"toc": { "toc": {
"base_numbering": 1, "base_numbering": 1,
......
...@@ -139,7 +139,7 @@ ...@@ -139,7 +139,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 2, "execution_count": 3,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:07:40.001750Z", "end_time": "2021-04-30T09:07:40.001750Z",
...@@ -157,7 +157,10 @@ ...@@ -157,7 +157,10 @@
"import numpy as np\n", "import numpy as np\n",
"from numpy import pi as PI\n", "from numpy import pi as PI\n",
"import matplotlib.pyplot as plt\n", "import matplotlib.pyplot as plt\n",
"import networkx as nx" "import networkx as nx\n",
"\n",
"import warnings\n",
"warnings.filterwarnings(\"ignore\")"
] ]
}, },
{ {
...@@ -169,7 +172,7 @@ ...@@ -169,7 +172,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 3, "execution_count": 4,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:07:40.192343Z", "end_time": "2021-04-30T09:07:40.192343Z",
...@@ -179,7 +182,7 @@ ...@@ -179,7 +182,7 @@
"outputs": [ "outputs": [
{ {
"data": { "data": {
"image/png": "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\n", "image/png": "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\n",
"text/plain": [ "text/plain": [
"<Figure size 432x288 with 1 Axes>" "<Figure size 432x288 with 1 Axes>"
] ]
...@@ -194,7 +197,7 @@ ...@@ -194,7 +197,7 @@
"G = nx.Graph()\n", "G = nx.Graph()\n",
"V = range(n)\n", "V = range(n)\n",
"G.add_nodes_from(V)\n", "G.add_nodes_from(V)\n",
"E = [(0, 1), (1, 2), (2, 3), (3, 0)]\n", "E = [(0, 1), (1, 2), (2, 3), (3, 0), (1, 3)]\n",
"G.add_edges_from(E)\n", "G.add_edges_from(E)\n",
"\n", "\n",
"# Print out the generated graph G\n", "# Print out the generated graph G\n",
...@@ -225,7 +228,7 @@ ...@@ -225,7 +228,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 4, "execution_count": 5,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:07:40.206426Z", "end_time": "2021-04-30T09:07:40.206426Z",
...@@ -237,7 +240,7 @@ ...@@ -237,7 +240,7 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"[[-1.0, 'z0,z1'], [-1.0, 'z1,z2'], [-1.0, 'z2,z3'], [-1.0, 'z3,z0']]\n" "[[-1.0, 'z0,z1'], [-1.0, 'z1,z2'], [-1.0, 'z2,z3'], [-1.0, 'z3,z0'], [-1.0, 'z1,z3']]\n"
] ]
} }
], ],
...@@ -265,7 +268,7 @@ ...@@ -265,7 +268,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 5, "execution_count": 6,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:07:40.501135Z", "end_time": "2021-04-30T09:07:40.501135Z",
...@@ -277,8 +280,8 @@ ...@@ -277,8 +280,8 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"[-4. 0. 0. 0. 0. 4. 0. 0. 0. 0. 4. 0. 0. 0. 0. -4.]\n", "[-5. 1. -1. 1. 1. 3. 1. -1. -1. 1. 3. 1. 1. -1. 1. -5.]\n",
"H_max: 4.0\n" "H_max: 3.0\n"
] ]
} }
], ],
...@@ -322,7 +325,7 @@ ...@@ -322,7 +325,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 6, "execution_count": 7,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:07:41.987233Z", "end_time": "2021-04-30T09:07:41.987233Z",
...@@ -381,7 +384,7 @@ ...@@ -381,7 +384,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 7, "execution_count": 8,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:07:43.856891Z", "end_time": "2021-04-30T09:07:43.856891Z",
...@@ -424,7 +427,7 @@ ...@@ -424,7 +427,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 8, "execution_count": 9,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:07:44.907375Z", "end_time": "2021-04-30T09:07:44.907375Z",
...@@ -460,32 +463,32 @@ ...@@ -460,32 +463,32 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"iter: 10 loss: -3.8886\n", "iter: 10 loss: -1.8359\n",
"iter: 20 loss: -3.9134\n", "iter: 20 loss: -2.5392\n",
"iter: 30 loss: -3.9659\n", "iter: 30 loss: -2.7250\n",
"iter: 40 loss: -3.9906\n", "iter: 40 loss: -2.8061\n",
"iter: 50 loss: -3.9979\n", "iter: 50 loss: -2.8748\n",
"iter: 60 loss: -3.9993\n", "iter: 60 loss: -2.9134\n",
"iter: 70 loss: -3.9998\n", "iter: 70 loss: -2.9302\n",
"iter: 80 loss: -3.9999\n", "iter: 80 loss: -2.9321\n",
"iter: 90 loss: -4.0000\n", "iter: 90 loss: -2.9321\n",
"iter: 100 loss: -4.0000\n", "iter: 100 loss: -2.9325\n",
"iter: 110 loss: -4.0000\n", "iter: 110 loss: -2.9327\n",
"iter: 120 loss: -4.0000\n", "iter: 120 loss: -2.9328\n",
"\n", "\n",
"The trained circuit:\n", "The trained circuit:\n",
"--H----*-----------------*--------------------------------------------------X----Rz(3.140)----X----Rx(0.824)----*-----------------*--------------------------------------------------X----Rz(0.737)----X----Rx(2.506)----*-----------------*--------------------------------------------------X----Rz(4.999)----X----Rx(4.854)----*-----------------*--------------------------------------------------X----Rz(0.465)----X----Rx(1.900)--\n", "--H----*-----------------*--------------------------------------------------x----Rz(2.379)----x----Rx(2.503)-----------------------------------*-----------------*--------------------------------------------------x----Rz(1.230)----x----Rx(0.792)-----------------------------------*-----------------*--------------------------------------------------x----Rz(4.375)----x----Rx(5.180)-----------------------------------*-----------------*--------------------------------------------------x----Rz(0.711)----x----Rx(2.353)---------------------------------\n",
" | | | | | | | | | | | | | | | | \n", " | | | | | | | | | | | | | | | | \n",
"--H----X----Rz(3.140)----X----*-----------------*---------------------------|-----------------|----Rx(0.824)----X----Rz(0.737)----X----*-----------------*---------------------------|-----------------|----Rx(2.506)----X----Rz(4.999)----X----*-----------------*---------------------------|-----------------|----Rx(4.854)----X----Rz(0.465)----X----*-----------------*---------------------------|-----------------|----Rx(1.900)--\n", "--H----x----Rz(2.379)----x----*-----------------*---------------------------|-----------------|--------*---------------------*----Rx(2.503)----x----Rz(1.230)----x----*-----------------*---------------------------|-----------------|--------*---------------------*----Rx(0.792)----x----Rz(4.375)----x----*-----------------*---------------------------|-----------------|--------*---------------------*----Rx(5.180)----x----Rz(0.711)----x----*-----------------*---------------------------|-----------------|--------*---------------------*----Rx(2.353)--\n",
" | | | | | | | | | | | | | | | | \n", " | | | | | | | | | | | | | | | | | | | | | | | | \n",
"--H---------------------------X----Rz(3.140)----X----*-----------------*----|-----------------|----Rx(0.824)---------------------------X----Rz(0.737)----X----*-----------------*----|-----------------|----Rx(2.506)---------------------------X----Rz(4.999)----X----*-----------------*----|-----------------|----Rx(4.854)---------------------------X----Rz(0.465)----X----*-----------------*----|-----------------|----Rx(1.900)--\n", "--H---------------------------x----Rz(2.379)----x----*-----------------*----|-----------------|--------|---------------------|----Rx(2.503)---------------------------x----Rz(1.230)----x----*-----------------*----|-----------------|--------|---------------------|----Rx(0.792)---------------------------x----Rz(4.375)----x----*-----------------*----|-----------------|--------|---------------------|----Rx(5.180)---------------------------x----Rz(0.711)----x----*-----------------*----|-----------------|--------|---------------------|----Rx(2.353)--\n",
" | | | | | | | | | | | | | | | | \n", " | | | | | | | | | | | | | | | | | | | | | | | | \n",
"--H--------------------------------------------------X----Rz(3.140)----X----*-----------------*----Rx(0.824)--------------------------------------------------X----Rz(0.737)----X----*-----------------*----Rx(2.506)--------------------------------------------------X----Rz(4.999)----X----*-----------------*----Rx(4.854)--------------------------------------------------X----Rz(0.465)----X----*-----------------*----Rx(1.900)--\n", "--H--------------------------------------------------x----Rz(2.379)----x----*-----------------*--------x--------Rz(2.379)----x----Rx(2.503)--------------------------------------------------x----Rz(1.230)----x----*-----------------*--------x--------Rz(1.230)----x----Rx(0.792)--------------------------------------------------x----Rz(4.375)----x----*-----------------*--------x--------Rz(4.375)----x----Rx(5.180)--------------------------------------------------x----Rz(0.711)----x----*-----------------*--------x--------Rz(0.711)----x----Rx(2.353)--\n",
" \n", " \n",
"Optimized parameters gamma:\n", "Optimized parameters gamma:\n",
" [3.14046713 0.73681226 4.99897226 0.46481489]\n", " [2.37918879 1.22914743 4.37582352 0.71142941]\n",
"Optimized parameters beta:\n", "Optimized parameters beta:\n",
" [0.82379898 2.50618308 4.85422542 1.90024859]\n" " [2.50287593 0.79179726 5.17941547 2.35294027]\n"
] ]
} }
], ],
...@@ -545,7 +548,7 @@ ...@@ -545,7 +548,7 @@
"outputs": [ "outputs": [
{ {
"data": { "data": {
"image/png": "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\n", "image/png": "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\n",
"text/plain": [ "text/plain": [
"<Figure size 432x288 with 1 Axes>" "<Figure size 432x288 with 1 Axes>"
] ]
...@@ -587,12 +590,12 @@ ...@@ -587,12 +590,12 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"The bit string form of the cut found: 1010\n" "The bit string form of the cut found: 0101\n"
] ]
}, },
{ {
"data": { "data": {
"image/png": "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\n", "image/png": "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\n",
"text/plain": [ "text/plain": [
"<Figure size 432x288 with 1 Axes>" "<Figure size 432x288 with 1 Axes>"
] ]
...@@ -609,10 +612,14 @@ ...@@ -609,10 +612,14 @@
"# Draw the cut corresponding to the bit string obtained above on the graph\n", "# Draw the cut corresponding to the bit string obtained above on the graph\n",
"node_cut = [\"blue\" if cut_bitstring[v] == \"1\" else \"red\" for v in V]\n", "node_cut = [\"blue\" if cut_bitstring[v] == \"1\" else \"red\" for v in V]\n",
"\n", "\n",
"edge_cut = [\n", "edge_cut = []\n",
" \"solid\" if cut_bitstring[u] == cut_bitstring[v] else \"dashed\"\n", "for u in range(n):\n",
" for (u, v) in E\n", " for v in range(u+1,n):\n",
" ]\n", " if (u, v) in E or (v, u) in E:\n",
" if cut_bitstring[u] == cut_bitstring[v]:\n",
" edge_cut.append(\"solid\")\n",
" else:\n",
" edge_cut.append(\"dashed\")\n",
"nx.draw(\n", "nx.draw(\n",
" G,\n", " G,\n",
" pos,\n", " pos,\n",
...@@ -646,6 +653,9 @@ ...@@ -646,6 +653,9 @@
} }
], ],
"metadata": { "metadata": {
"interpreter": {
"hash": "3b61f83e8397e1c9fcea57a3d9915794102e67724879b24295f8014f41a14d85"
},
"kernelspec": { "kernelspec": {
"display_name": "Python 3", "display_name": "Python 3",
"language": "python", "language": "python",
...@@ -661,7 +671,7 @@ ...@@ -661,7 +671,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.8.3" "version": "3.7.11"
}, },
"toc": { "toc": {
"base_numbering": 1, "base_numbering": 1,
......
closePrice0,closePrice1,closePrice2,closePrice3,closePrice4,closePrice5,closePrice6,closePrice7,closePrice8,closePrice9,closePrice10,closePrice11 closePrice0,closePrice1,closePrice2,closePrice3,closePrice4,closePrice5,closePrice6,closePrice7,closePrice8,closePrice9,closePrice10,closePrice11
16.87,32.56,5.4,3.71,5.72,7.62,3.7,6.94,5.43,3.46,8.22,4.56 16.87,32.56,5.4,3.71,5.72,7.62,3.7,6.94,5.43,3.46,8.22,4.56
17.18,32.05,5.48,3.75,5.75,7.56,3.7,6.89,5.37,3.45,8.14,4.54 17.18,32.05,5.48,3.75,5.75,7.56,3.7,6.89,5.37,3.45,8.14,4.54
17.07,31.51,5.46,3.73,5.74,7.68,3.68,6.91,5.37,3.41,8.1,4.55 17.07,31.51,5.46,3.73,5.74,7.68,3.68,6.91,5.37,3.41,8.1,4.55
17.15,31.76,5.49,3.79,5.81,7.75,3.7,6.97,5.42,3.5,8.16,4.58 17.15,31.76,5.49,3.79,5.81,7.75,3.7,6.97,5.42,3.5,8.16,4.58
16.66,31.68,5.39,3.72,5.69,7.79,3.63,6.85,5.29,3.42,7.93,4.48 16.66,31.68,5.39,3.72,5.69,7.79,3.63,6.85,5.29,3.42,7.93,4.48
16.79,32.2,5.47,3.77,5.79,7.84,3.66,6.94,5.41,3.46,8.02,4.56 16.79,32.2,5.47,3.77,5.79,7.84,3.66,6.94,5.41,3.46,8.02,4.56
16.69,31.46,5.46,3.76,5.77,7.82,3.63,7.01,5.42,3.48,8,4.53 16.69,31.46,5.46,3.76,5.77,7.82,3.63,7.01,5.42,3.48,8,4.53
16.99,31.68,5.53,3.74,5.8,7.8,3.63,7.03,5.39,3.47,8.03,4.53 16.99,31.68,5.53,3.74,5.8,7.8,3.63,7.03,5.39,3.47,8.03,4.53
16.76,31.39,5.5,3.78,5.89,7.92,3.66,7.04,5.45,3.48,8.05,4.56 16.76,31.39,5.5,3.78,5.89,7.92,3.66,7.04,5.45,3.48,8.05,4.56
16.52,30.49,5.47,3.71,5.78,7.96,3.63,7.01,5.43,3.45,7.95,4.47 16.52,30.49,5.47,3.71,5.78,7.96,3.63,7.01,5.43,3.45,7.95,4.47
16.33,30.53,5.39,3.61,5.7,7.93,3.6,6.99,5.35,3.4,7.92,4.42 16.33,30.53,5.39,3.61,5.7,7.93,3.6,6.99,5.35,3.4,7.92,4.42
16.39,30.46,5.35,3.58,5.69,7.87,3.59,6.95,5.26,3.41,7.93,4.38 16.39,30.46,5.35,3.58,5.69,7.87,3.59,6.95,5.26,3.41,7.93,4.38
16.45,29.87,5.37,3.61,5.75,7.86,3.63,6.96,5.54,3.42,7.99,4.35 16.45,29.87,5.37,3.61,5.75,7.86,3.63,6.96,5.54,3.42,7.99,4.35
16,29.21,5.24,3.53,5.7,7.82,3.6,6.87,6.09,3.32,7.9,4.32 16,29.21,5.24,3.53,5.7,7.82,3.6,6.87,6.09,3.32,7.9,4.32
16.09,30.11,5.26,3.5,5.71,7.9,3.61,6.87,6.7,3.33,8.01,4.34 16.09,30.11,5.26,3.5,5.71,7.9,3.61,6.87,6.7,3.33,8.01,4.34
15.54,28.98,5.08,3.42,5.54,7.7,3.54,6.58,7.37,3.23,7.73,4.13 15.54,28.98,5.08,3.42,5.54,7.7,3.54,6.58,7.37,3.23,7.73,4.13
13.99,26.63,4.57,3.08,4.99,6.93,3.19,5.92,8.11,2.91,6.96,3.72 13.99,26.63,4.57,3.08,4.99,6.93,3.19,5.92,8.11,2.91,6.96,3.72
14.6,27.62,4.44,2.95,4.89,6.91,3.27,5.78,8.1,2.96,7.01,3.51 14.6,27.62,4.44,2.95,4.89,6.91,3.27,5.78,8.1,2.96,7.01,3.51
14.63,27.64,4.5,3.04,4.94,7.18,3.27,5.89,8.91,3.02,7.06,3.61 14.63,27.64,4.5,3.04,4.94,7.18,3.27,5.89,8.91,3.02,7.06,3.61
14.77,27.9,4.56,3.05,5.08,7.31,3.31,5.94,9.8,3.06,7.08,3.88 14.77,27.9,4.56,3.05,5.08,7.31,3.31,5.94,9.8,3.06,7.08,3.88
14.62,27.5,4.52,3.05,5.39,7.35,3.3,5.93,10.78,3.05,7.07,3.87 14.62,27.5,4.52,3.05,5.39,7.35,3.3,5.93,10.78,3.05,7.07,3.87
14.5,28.67,4.59,3.13,5.35,7.53,3.32,6.06,11.86,3.13,7.15,3.9 14.5,28.67,4.59,3.13,5.35,7.53,3.32,6.06,11.86,3.13,7.15,3.9
14.79,29.08,4.66,3.12,5.23,7.47,3.33,6.16,10.67,3.15,7.17,3.91 14.79,29.08,4.66,3.12,5.23,7.47,3.33,6.16,10.67,3.15,7.17,3.91
14.77,29.08,4.67,3.14,5.26,7.48,3.38,6.18,11.36,3.17,7.21,3.95 14.77,29.08,4.67,3.14,5.26,7.48,3.38,6.18,11.36,3.17,7.21,3.95
14.65,29.95,4.66,3.11,5.19,7.35,3.36,6.15,10.56,3.14,7.19,3.94 14.65,29.95,4.66,3.11,5.19,7.35,3.36,6.15,10.56,3.14,7.19,3.94
15.03,30.8,4.72,3.07,5.18,7.33,3.34,6.11,9.56,3.15,7.29,3.96 15.03,30.8,4.72,3.07,5.18,7.33,3.34,6.11,9.56,3.15,7.29,3.96
15.37,30.42,4.84,3.23,5.31,7.46,3.39,6.35,9.15,3.18,7.41,4.04 15.37,30.42,4.84,3.23,5.31,7.46,3.39,6.35,9.15,3.18,7.41,4.04
15.2,29.7,4.81,3.3,5.33,7.47,3.39,6.34,9.11,3.17,7.4,4.06 15.2,29.7,4.81,3.3,5.33,7.47,3.39,6.34,9.11,3.17,7.4,4.06
15.24,29.65,4.84,3.31,5.31,7.39,3.37,6.26,8.89,3.12,7.34,3.99 15.24,29.65,4.84,3.31,5.31,7.39,3.37,6.26,8.89,3.12,7.34,3.99
15.59,29.85,4.88,3.3,5.38,7.47,3.42,6.44,8.36,3.15,7.42,4.04 15.59,29.85,4.88,3.3,5.38,7.47,3.42,6.44,8.36,3.15,7.42,4.04
15.58,29.25,4.89,3.33,5.39,7.48,3.43,6.46,8.68,3.16,7.52,4.03 15.58,29.25,4.89,3.33,5.39,7.48,3.43,6.46,8.68,3.16,7.52,4.03
15.23,28.9,4.82,3.31,5.41,8.06,3.37,6.41,8.77,3.12,7.41,3.97 15.23,28.9,4.82,3.31,5.41,8.06,3.37,6.41,8.77,3.12,7.41,3.97
15.04,29.33,4.74,3.22,5.28,8.02,3.32,6.32,9.65,3.06,7.31,3.9 15.04,29.33,4.74,3.22,5.28,8.02,3.32,6.32,9.65,3.06,7.31,3.9
14.99,30.11,4.84,3.31,5.3,8.01,3.36,6.32,9.11,3.13,7.51,3.9 14.99,30.11,4.84,3.31,5.3,8.01,3.36,6.32,9.11,3.13,7.51,3.9
15.11,29.67,4.79,3.25,5.38,8.11,3.37,6.42,8.41,3.15,7.5,3.88 15.11,29.67,4.79,3.25,5.38,8.11,3.37,6.42,8.41,3.15,7.5,3.88
14.5,29.59,4.63,3.12,5.12,7.87,3.3,6.15,8.4,3.08,7.18,3.76 14.5,29.59,4.63,3.12,5.12,7.87,3.3,6.15,8.4,3.08,7.18,3.76
\ No newline at end of file
...@@ -91,7 +91,7 @@ ...@@ -91,7 +91,7 @@
"source": [ "source": [
"在 `__init__()` 函数中,我们需要初始化所有的参与方、量子态以及 QNN 的参数。\n", "在 `__init__()` 函数中,我们需要初始化所有的参与方、量子态以及 QNN 的参数。\n",
"\n", "\n",
"- `self.add_new_party(qubits_number, party_name=None)` 是用于添加一个新的参与方的函数,第一个参数代表该参与方有几个量子比特;第二个参数是可选参数,代表着参与者的名字。在协议中,我们可以选择是用过名字来指定参与方,也可以选择用编号来指定。如果我们希望使用名字,那么只需要在 `add_new_party` 函数中给 `party_name` 命名;如果希望使用编号,那么我们就不用给第二个参数赋值,第一个参与方会自动编号为 0,每增加一个参与方,其编号都会加一,同时该函数会将所添加的 party 的 ID 返回,其值根据定义会是 `int` 或者 `str`。\n", "- `self.add_new_party(qubits_number, party_name=None)` 是用于添加一个新的参与方的函数,第一个参数代表该参与方有几个量子比特;第二个参数是可选参数,代表着参与者的名字。在协议中,我们可以选择使用名字来指定参与方,也可以选择用编号来指定。如果我们希望使用名字,那么只需要在 `add_new_party` 函数中给 `party_name` 命名;如果希望使用编号,那么我们就不用给第二个参数赋值,第一个参与方会自动编号为 0,每增加一个参与方,其编号都会加一,同时该函数会将所添加的 party 的 ID 返回,其值根据定义会是 `int` 或者 `str`。\n",
"\n", "\n",
"- `self.set_init_state(state, which_qubits)` 是用于设置协议的初始态的函数。第一个参数 `state` 是量子态,必须是密度矩阵的形式;第二个参数 `which_qubits` 是定位量子比特(哪一参与方的第几个量子比特,如 `(\"Alice\", 0)`)。需要说明的是,我们必须初始化所有的量子比特,否则程序将出现错误。" "- `self.set_init_state(state, which_qubits)` 是用于设置协议的初始态的函数。第一个参数 `state` 是量子态,必须是密度矩阵的形式;第二个参数 `which_qubits` 是定位量子比特(哪一参与方的第几个量子比特,如 `(\"Alice\", 0)`)。需要说明的是,我们必须初始化所有的量子比特,否则程序将出现错误。"
] ]
...@@ -100,7 +100,7 @@ ...@@ -100,7 +100,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"在 `forward()` 函数中,我们需要定义协议的流程。如果我们想要训练一个模型,那么需要定义损失函数,并设置为 `forward()` 的返回值,这样才能不断更新参数使得损失函数最小化。如果我们仅仅是想要验证某个协议的结果,我们就做上述的事情,只需要把协议的流程定义清,就可以把我们感兴趣的值设为返回值。在 `forward()` 函数中,我们主要做两件事情--量子操作和测量,我们为他们提供了相应的函数:\n", "在 `forward()` 函数中,我们需要定义协议的流程。如果我们想要训练一个模型,那么需要定义损失函数,并设置为 `forward()` 的返回值,这样才能不断更新参数使得损失函数最小化。如果我们仅仅是想要验证某个协议的结果,我们就做上述的事情,只需要把协议的流程定义清,就可以把我们感兴趣的值设为返回值。在 `forward()` 函数中,我们主要做两件事情--量子操作和测量,我们为他们提供了相应的函数:\n",
"\n", "\n",
"- `self.create_ansatz(party_id)` 是为某一参与方创建本地量子电路的函数。所以参数 `party_id` 用来指定参与方。举个例子 `cir1 = self.create_ansatz(\"Alice\")` 为 Alice 创建了电路。之后,我们可以在电路中添加不同的操作比如 X 门, CNOT 门等,也可以在添加门之后通过 `run()` 函数来运行电路,得到运行后的结果,如 `status_out = cir1.run(status)`。\n", "- `self.create_ansatz(party_id)` 是为某一参与方创建本地量子电路的函数。所以参数 `party_id` 用来指定参与方。举个例子 `cir1 = self.create_ansatz(\"Alice\")` 为 Alice 创建了电路。之后,我们可以在电路中添加不同的操作比如 X 门, CNOT 门等,也可以在添加门之后通过 `run()` 函数来运行电路,得到运行后的结果,如 `status_out = cir1.run(status)`。\n",
"\n", "\n",
...@@ -141,7 +141,7 @@ ...@@ -141,7 +141,7 @@
"\n", "\n",
"[1] Chitambar, Eric, et al. \"Everything you always wanted to know about LOCC (but were afraid to ask).\" [Communications in Mathematical Physics 328.1 (2014): 303-326.](https://link.springer.com/article/10.1007/s00220-014-1953-9)\n", "[1] Chitambar, Eric, et al. \"Everything you always wanted to know about LOCC (but were afraid to ask).\" [Communications in Mathematical Physics 328.1 (2014): 303-326.](https://link.springer.com/article/10.1007/s00220-014-1953-9)\n",
"\n", "\n",
"[2] Zhao, Xuanqiang, et al. \"LOCCNet: a machine learning framework for distributed quantum information processing.\" [arXiv:2101.12190 (2021).](https://arxiv.org/abs/2101.12190)\n", "[2] Zhao, Xuanqiang, et al. \"Practical distributed quantum information processing with LOCCNet.\" [npj Quantum Information 7, 159 (2021).](https://www.nature.com/articles/s41534-021-00496-x)\n",
"\n", "\n",
"[3] Bennett, Charles H., et al. \"Teleporting an unknown quantum state via dual classical and Einstein-Podolsky-Rosen channels.\" [Physical Review Letters 70.13 (1993): 1895.](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.70.1895)\n", "[3] Bennett, Charles H., et al. \"Teleporting an unknown quantum state via dual classical and Einstein-Podolsky-Rosen channels.\" [Physical Review Letters 70.13 (1993): 1895.](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.70.1895)\n",
"\n", "\n",
......
...@@ -133,7 +133,7 @@ ...@@ -133,7 +133,7 @@
"\n", "\n",
"[1] Chitambar, Eric, et al. \"Everything you always wanted to know about LOCC (but were afraid to ask).\" [Communications in Mathematical Physics 328.1 (2014): 303-326.](https://link.springer.com/article/10.1007/s00220-014-1953-9)\n", "[1] Chitambar, Eric, et al. \"Everything you always wanted to know about LOCC (but were afraid to ask).\" [Communications in Mathematical Physics 328.1 (2014): 303-326.](https://link.springer.com/article/10.1007/s00220-014-1953-9)\n",
"\n", "\n",
"[2] Zhao, Xuanqiang, et al. \"LOCCNet: a machine learning framework for distributed quantum information processing.\" [arXiv:2101.12190 (2021).](https://arxiv.org/abs/2101.12190)\n", "[2] Zhao, Xuanqiang, et al. \"Practical distributed quantum information processing with LOCCNet.\" [npj Quantum Information 7, 159 (2021).](https://www.nature.com/articles/s41534-021-00496-x)\n",
"\n", "\n",
"[3] Bennett, Charles H., et al. \"Teleporting an unknown quantum state via dual classical and Einstein-Podolsky-Rosen channels.\" [Physical Review Letters 70.13 (1993): 1895.](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.70.1895)\n", "[3] Bennett, Charles H., et al. \"Teleporting an unknown quantum state via dual classical and Einstein-Podolsky-Rosen channels.\" [Physical Review Letters 70.13 (1993): 1895.](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.70.1895)\n",
"\n", "\n",
...@@ -167,7 +167,7 @@ ...@@ -167,7 +167,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.7.9" "version": "3.7.10"
}, },
"toc": { "toc": {
"base_numbering": 1, "base_numbering": 1,
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
"source": [ "source": [
"## 概览\n", "## 概览\n",
"\n", "\n",
"本教程我们将讨论量子分类器(quantum classifier)的原理,以及如何利用量子神经网络(quantum neural network, QNN)来完成**分类**任务。这类方法早期工作的主要代表是 Mitarai et al.(2018) 的量子电路学习 [(Quantum Circuit Learning, QCL)](https://arxiv.org/abs/1803.00745) [1], Farhi & Neven (2018) [2] 和 Schuld et al.(2018) 的中心电路量子分类器 [Circuit-Centric Quantum Classifiers](https://arxiv.org/abs/1804.00633) [3]。这里我们以第一类的 QCL 框架应用于监督学习(Supervised learning)为例进行介绍,通常我们需要先将经典数据编码成量子数据,然后通过训练量子神经网络的参数,最终得到一个最优的分类器。" "本教程我们将讨论量子分类器(quantum classifier)的原理,以及如何利用量子神经网络(quantum neural network, QNN)来完成**分类**任务。这类方法早期工作的主要代表是 Mitarai et al.(2018) 的量子电路学习 [(Quantum Circuit Learning, QCL)](https://arxiv.org/abs/1803.00745) [1], Farhi & Neven (2018) [2] 和 Schuld et al.(2018) 的中心电路量子分类器 [Circuit-Centric Quantum Classifiers](https://arxiv.org/abs/1804.00633) [3]。这里我们以第一类的 QCL 框架应用于监督学习(Supervised learning)为例进行介绍,通常我们需要先将经典数据编码成量子数据,然后通过训练量子神经网络的参数,最终得到一个最优的分类器。"
] ]
}, },
{ {
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
"\n", "\n",
"这里我们给出实现量子电路学习 (QCL) 框架下量子分类器的一个流程。\n", "这里我们给出实现量子电路学习 (QCL) 框架下量子分类器的一个流程。\n",
"\n", "\n",
"1. 将经典数据编码$x^k$为量子数据$\\lvert \\psi_{\\rm in}\\rangle^k$。本教材采用角度编码。关于编码方式的具体操作,见[量子态编码经典数据](./DataEncoding_EN.ipynb)。用户也可以尝试其他编码,如振幅编码,体验不同编码方式学习效率的区别。\n", "1. 将经典数据编码$x^k$为量子数据$\\lvert \\psi_{\\rm in}\\rangle^k$。本教程采用角度编码。关于编码方式的具体操作,见[量子态编码经典数据](./DataEncoding_CN.ipynb)。用户也可以尝试其他编码,如振幅编码,体验不同编码方式对分类器学习效率的影响。\n",
"2. 构建可调参数量子电路,对应幺正变换(unitary gate)$U(\\theta)$。\n", "2. 构建可调参数量子电路,对应幺正变换(unitary gate)$U(\\theta)$。\n",
"3. 对每一个量子数据$\\lvert\\psi_{\\rm in}\\rangle^k$,通过参数化量子电路$U(\\theta)$,得到输出态$\\lvert \\psi_{\\rm out}\\rangle^k = U(\\theta)\\lvert \\psi_{\\rm in} \\rangle^k$。\n", "3. 对每一个量子数据$\\lvert\\psi_{\\rm in}\\rangle^k$,通过参数化量子电路$U(\\theta)$,得到输出态$\\lvert \\psi_{\\rm out}\\rangle^k = U(\\theta)\\lvert \\psi_{\\rm in} \\rangle^k$。\n",
"4. 对每一个量子数据得到的输出量子态$\\lvert \\psi_{\\rm out}\\rangle^k$,通过测量与数据后处理,得到标签 $\\tilde{y}^{k}$。\n", "4. 对每一个量子数据得到的输出量子态$\\lvert \\psi_{\\rm out}\\rangle^k$,通过测量与数据后处理,得到标签 $\\tilde{y}^{k}$。\n",
...@@ -69,9 +69,18 @@ ...@@ -69,9 +69,18 @@
"start_time": "2021-03-02T09:15:03.413324Z" "start_time": "2021-03-02T09:15:03.413324Z"
} }
}, },
"outputs": [], "outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\Users\\yeruilin\\Anaconda3\\envs\\paddle_quantum_env\\lib\\site-packages\\matplotlib_inline\\config.py:66: DeprecationWarning: InlineBackend._figure_formats_changed is deprecated in traitlets 4.1: use @observe and @unobserve instead.\n",
" def _figure_formats_changed(self, name, old, new):\n"
]
}
],
"source": [ "source": [
"# 导入numpy与paddle\n", "# 导入 numpy 与 paddle\n",
"import numpy as np\n", "import numpy as np\n",
"import paddle\n", "import paddle\n",
"\n", "\n",
...@@ -79,8 +88,8 @@ ...@@ -79,8 +88,8 @@
"from paddle_quantum.circuit import UAnsatz\n", "from paddle_quantum.circuit import UAnsatz\n",
"# 一些用到的函数\n", "# 一些用到的函数\n",
"from numpy import pi as PI\n", "from numpy import pi as PI\n",
"from paddle import matmul, transpose # paddle矩阵乘法与转置\n", "from paddle import matmul, transpose, reshape # paddle 矩阵乘法与转置\n",
"from paddle_quantum.utils import pauli_str_to_matrix,dagger # 得到N量子比特泡利矩阵,复共轭\n", "from paddle_quantum.utils import pauli_str_to_matrix,dagger # 得到 N 量子比特泡利矩阵,复共轭\n",
"\n", "\n",
"# 作图与计算时间\n", "# 作图与计算时间\n",
"from matplotlib import pyplot as plt\n", "from matplotlib import pyplot as plt\n",
...@@ -100,18 +109,19 @@ ...@@ -100,18 +109,19 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"# 训练参数设置\n", "# 数据集参数设置\n",
"Ntrain = 200 # 规定训练集大小\n", "Ntrain = 200 # 规定训练集大小\n",
"Ntest = 100 # 规定测试集大小\n", "Ntest = 100 # 规定测试集大小\n",
"gap = 0.5 # 设定决策边界的宽度\n", "boundary_gap = 0.5 # 设置决策边界的宽度\n",
"seed_data = 2 # 固定随机种子\n",
"# 训练参数设置\n",
"N = 4 # 所需的量子比特数量\n", "N = 4 # 所需的量子比特数量\n",
"DEPTH = 1 # 采用的电路深度\n", "DEPTH = 1 # 采用的电路深度\n",
"BATCH = 20 # 训练时 batch 的大小\n", "BATCH = 20 # 训练时 batch 的大小\n",
"EPOCH = int(200 * BATCH / Ntrain) \n", "EPOCH = int(200 * BATCH / Ntrain)\n",
" # 训练 epoch 轮数,使得总迭代次数 EPOCH * (Ntrain / BATCH) 在200左右\n", " # 训练 epoch 轮数,使得总迭代次数 EPOCH * (Ntrain / BATCH) 在200左右\n",
"LR = 0.01 # 设置学习速率\n", "LR = 0.01 # 设置学习速率\n",
"seed_paras = 19 # 设置随机种子用以初始化各种参数\n", "seed_paras = 19 # 设置随机种子用以初始化各种参数"
"seed_data = 2 # 固定生成数据集所需要的随机种子"
] ]
}, },
{ {
...@@ -120,7 +130,7 @@ ...@@ -120,7 +130,7 @@
"source": [ "source": [
"### 数据集的生成\n", "### 数据集的生成\n",
"\n", "\n",
"对于监督学习来说,我们绕不开的一个问题就是——采用的数据集是什么样的?在这个教程中我们按照论文 [1] 里所提及方法生成简单的圆形决策边界二分数据集 $\\{(x^{k}, y^{k})\\}$。其中数据点 $x^{k}\\in \\mathbb{R}^{2}$,标签 $y^{k} \\in \\{0,1\\}$。\n", "对于监督学习来说,我们绕不开的一个问题就是——采用什么样的数据集呢?在这个教程中我们按照论文 [1] 里所提及方法生成简单的圆形决策边界二分数据集 $\\{(x^{k}, y^{k})\\}$。其中数据点 $x^{k}\\in \\mathbb{R}^{2}$,标签 $y^{k} \\in \\{0,1\\}$。\n",
"\n", "\n",
"<img src=\"./figures/qclassifier-fig-data-cn.png\" width=\"400px\" /> \n", "<img src=\"./figures/qclassifier-fig-data-cn.png\" width=\"400px\" /> \n",
"<center> 图 2:生成的数据集和对应的决策边界 </center>\n", "<center> 图 2:生成的数据集和对应的决策边界 </center>\n",
...@@ -137,7 +147,7 @@ ...@@ -137,7 +147,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 3, "execution_count": 4,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-03-02T09:15:04.631031Z", "end_time": "2021-03-02T09:15:04.631031Z",
...@@ -183,7 +193,7 @@ ...@@ -183,7 +193,7 @@
" print(\"训练集的维度大小 x {} 和 y {}\".format(np.shape(train_x[0:Ntrain]), np.shape(train_y[0:Ntrain])))\n", " print(\"训练集的维度大小 x {} 和 y {}\".format(np.shape(train_x[0:Ntrain]), np.shape(train_y[0:Ntrain])))\n",
" print(\"测试集的维度大小 x {} 和 y {}\".format(np.shape(train_x[Ntrain:]), np.shape(train_y[Ntrain:])), \"\\n\")\n", " print(\"测试集的维度大小 x {} 和 y {}\".format(np.shape(train_x[Ntrain:]), np.shape(train_y[Ntrain:])), \"\\n\")\n",
"\n", "\n",
" return train_x[0:Ntrain], train_y[0:Ntrain], train_x[Ntrain:], train_y[Ntrain:]\n" " return train_x[0:Ntrain], train_y[0:Ntrain], train_x[Ntrain:], train_y[Ntrain:]"
] ]
}, },
{ {
...@@ -195,7 +205,7 @@ ...@@ -195,7 +205,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 4, "execution_count": 6,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
...@@ -225,7 +235,7 @@ ...@@ -225,7 +235,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 5, "execution_count": 7,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-03-02T09:15:06.422981Z", "end_time": "2021-03-02T09:15:06.422981Z",
...@@ -245,7 +255,7 @@ ...@@ -245,7 +255,7 @@
}, },
{ {
"data": { "data": {
"image/png": "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", "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYIAAAD4CAYAAADhNOGaAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAAsTAAALEwEAmpwYAAApn0lEQVR4nO2df6xexXnnP4+vYydu1Ma89mYdwNeQZZuQ3QrCVZSkUpqkJCHuClOVtiSG3qRUXm6b7kpRqxhZ6kZsrdL+Q6gSRCxKcLlXCQlVFLclYoGEXWk3kFx2AfNDxsYJYErCxQ6RIigJZvaPc974+PX5/XPOe74fafSeM+fX886ZM8/MPM/MmHMOIYQQw2VV1wIIIYToFikCIYQYOFIEQggxcKQIhBBi4EgRCCHEwFndtQBl2LBhg9uyZUvXYgghRK944IEHXnDObZyM76Ui2LJlC8vLy12LIYQQvcLMnoqLV9eQEEIMHCkCIYQYOFIEQggxcKQIhBBi4EgRCCHEwKlFEZjZzWb2vJk9knDczOxvzeyQmT1sZu+MHJs3s4NhmK9DHiHKsLQEW7bAqlXB79JS1xL5ic/p5JNsPsmSiXOucgDeB7wTeCTh+Fbgm4AB7wbuD+NPAw6Hv+vD7fVZz7vgggtcn1lcdG521jmz4HdxsWuJxOKic+vWOQcnwrp1ejeTNJVOdXwTPr1Dn2SJAiy7uDI6LrJMALakKIIvAh+L7B8ANgEfA76YdF5S6LMiiMsgZs4tLHQtWbP4rvxmZ09+J+MwO9u1ZH7RRDrVVWj69A59kiVKkiJoy0ZwOvBMZP9IGJcUfwpmtsPMls1seWVlpTFBm2bXLnjppZPjnIMbb6y/6ehL03RpCXbsgKeeCv7rU08F+z41lZ9+ulj8UHkqdjhStXSK+yZeeimIL4JP79AnWfLQG2Oxc26Pc27OOTe3ceMpI6R7Q9KH5FzxjJ+GT4VvXR96k2zeXCy+SXxR4JMsLYFZ/LEy6TT+n3UpF5/eoU+y5KEtRfAscGZk/4wwLil+akn6kKDe2oJPhW8fake7d8O6dSfHrVsXxLeJTwp8kl27ApkmMSueTtH/mUTRQrPKO6yifOOu9SU/5Sauv6hMIN1G8FucbCz+rjthLP4+gaF4fbh9Wtaz6rARdNVnHddvGNd/WFU+s/hnmNX4Z3Lia3/pJD7YMZpMq6byFBSXJel/VjWsLi46NxqduM9olH2fKjaKtGt9yE+T0KSxGPgy8Bzwc4J+/iuBq4CrwuMGfAF4EtgPzEWu/UPgUBg+med5VRVBlxb9tMw/fn4d8vlU+PrqQeEjTSlw3/JUmlKpUmiW+Z9V/pdP31keGlUEbYeqiiDp5c3MNK+9o7WVaPilX8qWr0jm6qrwTaoF+Vg78pGmChbf8pRP/zOP8k3Kv1Wu7QIpgghptZGmC83FRefWrDn5WWvWnPysumqFbWdA1fyr01Qa+panfPqfWcojTdYq13aBFEGErP7Jppt3WR9T35qbY/oqt280ocB9fDe+/M+swjrtnlWu7QIpgghxL6+O2lJd+FaLyItPBmpxMnXnKR+6O+JkKPs/0/5PVr6ucm3bSBFMsLgY2AS6aBHkla/rD60ovtV+xMn43q1Tlwx1fzvTZEyWIoghy1bQh8LXJ3woIETz+FC4tSlDU+6lXSBFEEOarWA0quURXtFGK6OPLRlRDB+6O9qWoUq+9umbkCKIIc6DB5x73eumrwDzrWYi+svQWgRJ+FTA5yVJEfRmrqEm2L4dbr4ZRqMTcaMRfOlLwbFpwqcpJ0S/8WH6hK5l8HkqkDJYoCT6xdzcnFteXu5ajF6xalWQYScxg9dea18e0W+WloJKxNNPB3MC7d7dfuWpSxmSJsubnYUf/KAdGcpgZg845+ZOiZciGAZ9zbhC+EhfK1ZJimDQXUNp+DoVcFm6bkoLMU1UmWbax7JFiiCGNvr/imSGOjLO9u2wZ0/QAjALfvfsmT5biBBtULZi5a1tIc6C7HtoeqnKpj0SinjwyNtHiPop4/Ezec3CQvF7dO3thNxH89O0j3KRzNB1xhFi2shTuYor9OuokHU9BiNJEchYHEPThtUihqa+GqWE8JWs73vcfRN1tzaL/w6LlgldO200aiw2s4vM7ICZHTKznTHHrzOzB8PwhJm9GDl2PHJsXx3yVKVpw2oRQ1NZo5SPBikhmqJIfs9aOjVuzE1SfbnocqveOm3ENROKBGCGYOWxs4E1wEPAuSnn/ylwc2T/p0Wf2XTXkHPNjhps2kYgu4IYEkXze1Z3a571Sqp00XY5IpmmbATAe4A7I/tXA1ennP9/gA9F9r1UBE1TJDMUzTiyK4ghUTS/l11DYFJB9LFy1aQiuBS4KbJ/BfD5hHNnCdY2nonEvQosA/cBl+R55jQogibp2iAlRJuUye9plaskRTH2EoITU9j3ZY6hMUmKoO1xBJcBtzvnjkfiZl1gvPg48Dkze2vchWa2w8yWzWx5ZWWlDVl7S5XBLkL0jTL5ffv2wDj72mvBb3Q8TdKYmxtuONHHfzwswbwZB1CROhTBs8CZkf0zwrg4LgO+HI1wzj0b/h4G7gXOj7vQObfHOTfnnJvbuHFjVZmngiQDmbcGKSEaoIn8nqQoyk7e2PYA0sLENROKBGA1cBg4ixPG4nfEnPc24AeE8xuFceuBteH2BuAgKYbmcVDXUHY/Zx+nyBWiLHXk9zz3KNsN5csAUpocUAZsBZ4g8B7aFcZdA1wcOeezwLUT170X2B8qj/3AlXmeJ0UQLJwjg7AQyRR1yMhTAJdxxPBpAGmjiqDtMHRFsLgYn1lkEBYioG6X0rL3dS5/K6KN7zpJEWjSuRR8HZSV1h8pg7AQxfvy0waZRcuBXbtgfr7Y5I15jNnj0cxF71EbcdrB99DWgDJfB2WlDXjxQT4huqZoX35Si2A0ql4OxJUla9YE9x53WyV19bZlI1CLIAGfl3ZMqh2MRppWWggo7lKa5HkE1cuBSXfU0Sgo4o8eDX6feirYTqKN6eKlCBLImo+kS5Iy7fXXdyOPEL5R1KU0aezAsWPx5xctB6LuqG98I/z85/mum51tp3InRZBAWo2ia9uBFpkRIp0y30jc2IEmBmfmVSKtjv2J6y/yPXRpI6hrXnIhhP80YStMs0fEubvWOSYI2QiKkVSjuOMOf20HQoh6aaL1nda1G22RAGzYAJdf3vzSllIEMYy7fq64Iti/9dYTTUWfbQdCiPpJm5eoTDdxknKBE/fasAE++cl4I3ITFU8pggmyFpfWhG5CCKi2EP2kcoGT73X0aLpBue6K5yAVQZoWz3IbrWuCq64NzkKIatTpYh53rzRqr3jGGQ58D1WMxVnGnzwDUaoab3werCaEyEed634UWRWtSlmBFq8PyFo8uo3FpbtewFoIUZ06v+Oke00yGgVG5bLG6kYXr+8TWcbeNubyl8FZiP5TZ1kRd681a4KCf2xQXlyEF15oZrzQ4BRBlrG3jcFaMjgL0X/qLCvi7nXzzUHBH+etVDtx/UW+hyZtBHWSZEuQjUCIYeDbAlFoPYITtPFytIKYEMPGxwpfo4oAuAg4ABwCdsYc/wSwAjwYhj+KHJsnWKLyIDCf53l9WJim6ZWGhBB+U6QMaKtimKQIVlftWjKzGeALwIeAI8D3zGyfc+6xiVNvc859auLa04D/BswBDnggvPbHVeXqGhmEhRg2ecuA8cC08TiC8cA0aG8iyTqMxe8CDjnnDjvnfgZ8BdiW89qPAHc5546Fhf9dBK2L3iODsBDDJm8ZkDUwrY3Bp3UogtOBZyL7R8K4SX7HzB42s9vN7MyC12JmO8xs2cyWV1ZWahC7WdpwQxVC+EveMiBrmcyy01gUoS330X8Etjjnfo2g1r+36A2cc3ucc3POubmNGzfWLmDdaM0AIYbN9u3B+sYzM8H+zEywP1kGpLUc2lopsQ5F8CxwZmT/jDDuFzjnjjrnXgl3bwIuyHttn0mbtVAIMd0sLcHevXD8eLB//HiwP1mbT2s5tGVrrEMRfA84x8zOMrM1wGXAvugJZrYpsnsx8Hi4fSfwYTNbb2brgQ+HcUII0Wvy1ubTeg/asjVW9hpyzr1qZp8iKMBngJudc4+a2TUErkr7gP9iZhcDrwLHCNxJcc4dM7P/TqBMAK5xziWsEiqEEP0hae6guPjt2+N7DHbvPtmjCJqxNQ5u0jkhhGiD1atPdAtFmZmBV1/Nf5+lpaAV8fTTQUtg9+76J52r3CIQQghxKnFKIC0+iaTWQp0MbtI5IYRog9nZYvFdIkUghBAN0KexRFIEYrqpa1im1hYVBenTWCIpghj0zU8JdQ3LbGt4p5g6+jKWSF5DE0xOAAVBc85XTS5SqGstQa0tKqYELVWZk7aGdIsWKDIsM60ZqKlkxZQjRTCBvnkPKdtXl3dYZlbXj6aSFVOOFMEE+uY9o0r/fF63jaxmYJ/cP4QogRTBBPrmPaNKX11et42sZmDd7h/yRhAZtJ5F4pYt8z00vVSl1hP2CLP49f7M6ntGm+uK+riQrfCKJrMICUtVqkUQQ19cvgZBHX11WdWrss3AMtU2eSOIDDrJInHawffQh8XrRU1UrR7lvT6pGZgWX0auNlo4otc0mUVIaBF0XqiXCVIEA6NKX12Vbp+0wr7sfdvshhK9pMkskqQI1DUk/CGpq6VKX10Vf+C0NnrZ+8obQWTQRRaRIhB+0NQ0DlVsDGmFfdn79mkCGtEJnWSRuGZC0QBcBBwADgE7Y45/GngMeBi4B5iNHDsOPBiGfXmep66hKaSp9nAVG0OaTPL+ET2EprqGzGwG+ALwUeBc4GNmdu7Eaf8PmHPO/RpwO/A3kWMvO+fOC8PFVeURPaWpId1VqldpbfS0+9bhBK6xBqJN4rRDkQC8B7gzsn81cHXK+ecD/zuy/9Oiz1SLYArxwYgaZ5Quaqiuo6Wg1oZoCBo0Fp8OPBPZPxLGJXEl8M3I/uvNbNnM7jOzS5IuMrMd4XnLKysrlQQWHtK1ETXJRgHFDNV1OIHX6UiuloXIQ5x2KBKAS4GbIvtXAJ9POPdy4D5gbSTu9PD3bOAHwFuznqkWwZTS9pDu6PNmZuppkdThBJ50DygmS56WhYbRDwqaGkdAzq4h4ELgceDfpNzrFuDSrGdKEQyQMgVWWlfPuHBOKnDLjuKpo4sr6R5m9Y6hUBfU4GhSEawGDgNnAWuAh4B3TJxzPvAkcM5E/Ppx6wDYABwEzs16phRBDylb81xcdG40OrUwyyqw4gq5NWuce93rsgv/pAI8z3+oy0aQpKSKKJSs1okPdhnRKo0pguDebAWeCAv7XWHcNcDF4fbdwI+YcBMF3gvsD5XHfuDKPM+TIugZZQvHuOvyFlhJhVyREJWxyH+oo7uljhZKVkGv6S4GR6OKoO0gRdAz6p6OIU+BlafbJy2sWnVyAd527TnP87IUzsJC/D0WFrr5T6JzkhSBRhaL5ik7RiBuneAoaaN4q64k9NprJ++3vXRdkhfV1q2B948ZXHFF+kjsO+6Iv/c4vmtPLeENUgSiecpOxzAzk3wsq8DavTsoLKsQdddse+m6uAFr8/Owd+8JBencyddMupi2veCO6C9xzQTfg7qGekZZG0Fa102efvesbqXZ2eTuk8muJx88bPLYPaIyq+tHTIC6hkRnlK15zs4mx+eptaZdPx4gdsMNMBrFnxet7ftQe87TDRWVWV0/Ii9x2sH3oBbBQGhzUZqua/t5yGoRFFlwRwwS5DUkeknVgizv9X0oMOMU1tg7qk2Z+5BWIhYpAjFdDLUw6vp/96X1JGJJUgQWHOsXc3Nzbnl5uWsxRFeMJ4iLTsy2bp08XppmaSnwXDp+/NRjs7OBzUV4jZk94Jybm4yXsVj0jzpn5xT5GCvfOCUAzY2nEK0gRSC6p+hUyW0P7ppm8qZ9nPKN4pymue4xUgSiW8qsVdz24C6fqbLeQJG0z6Nk61pnWrRPnOHA9yBj8RRRZtBTnwyWTRp3s9Ih69lF0r7IJH4asOYtyGtIeEnZGTC79p7JQ9MKK60gz/PsImmfNRNskXcnOiNJEchrSHTLli3xk8tNgxdK0/9t1apT5xuCYOTz5s3Zzy4q39JSYCt4+ung/j/9KRw9mv960TnyGhJ+Ms3TIDRt1E6zleR5dtG037795PWbr79+et/dwJAiEN3S5Rw+TS/s3rRRO60gz/PsImkfl1Y+zL8k6iGuv6hoAC4CDgCHgJ0xx9cCt4XH7we2RI5dHcYfAD6S53l12Aj60MUsGqSNhd3bMGonyVjns/tknBep0OCaxTMES1SezYk1i8+dOOePgRvD7cuA28Ltc8Pz1xKsefwkMJP1zKqKQPlatLawe5c1jjqevbjo3MxMelqJ3pCkCCobi83sPcBnnXMfCfevDlsafxU5587wnO+Y2Wrgh8BGYGf03Oh5ac+saiyeZvukyEmaofW115RJIH4qjyjjtBK9oUlj8enAM5H9I2Fc7DnOuVeBnwCjnNcCYGY7zGzZzJZXVlYqCayBqSKzD71KJmna9tAWWaOJhziAb0rpjbHYObfHOTfnnJvbuHFjpXtpYKrI9Jgpm0nKjJT2lTSlJ++gqaIORfAscGZk/4wwLvacsGvoV4CjOa+tnWn2WPQW32rJWR4vZTPJNE2Il6T0ZmaCtAK/3qkoT5zhoEgAVgOHCYy9Y2PxOybO+RNONhZ/Ndx+Bycbiw/TgrHYOXkNtUoZw6sPL2hh4YShdGYm2M+i7EhpH0l7b/K46CU0OcUEsBV4gsDrZ1cYdw1wcbj9euBrBG6i3wXOjly7K7zuAPDRPM/TFBOeklR4F51PyIdCpqwM07ZgfNF3OjOj2pXHNKoI2g5SBB6SVnAWrSX7UJiWlcEXJdZ0ayrpnaqF4DVJikBzDYl6SHO3hGKumFmunW1QRYbJOXl2725vtG1bq7clve9JhuRu2wM015BoljR3y6KGVx/curJkSDN+T87J0+aUC0nG6ssvr9egG/dO45BPdj+Iayb4HtQ15CF5Rurm7a7wpXuliKEUnBuNuu8KyeqyqTMdo+9Uo497AbIRiEapu/D2wWuoqKHUh37xPAvINFE4+6C8RSZSBKJ5fCi82yCr1t1lLTjvAjJNPXsI77/HJCkC2QhEfXTZN94mWbaKLvvFowPlkpiZSb9H0cF/4/OvuCLYv/XW6X7/U4gUgRBFyTKUdj1XyVghJ3H8ePKxolNkTNOUGh7R9kB8KQIhspj8KiGodY9Gp57b5lwlWaVFUqsgrbVQdIqMaZpSwxM60a1x/UW+B9kIRCPE9XFnGUG76hfPu7BOUQNu2uC/uP86TVNqeEKT4ynRgDIhUkgaiPWGN/i5QHve9RKKDm5Luu9oBC+/3J/06TFNjqfUgDIxDMp2riZ1ccQVctD9QKm86yUUNeAnDf6D+PSJHo+er6l8S9PFeEopAjE9VOlcLVqwd20Qbqq0SJqe+9ix+POPHdMC9jXTyTT5cf1FvgfZCEQsVTpXk64djaoNlCpjQ8hzTdsDuHyYCHDKib720SgIdZue0IAyMfVUMVxmTSlRxiBcprBeWDj1fyRd06ahWiOHG6Wt5JUiENNP1Vpr3QVrmXUYkpSZDzVvjRxujLYaXEmKQF5Dwn/yer60NQVzXoq6f6RN7dzmFNyiddqaeb0RryEzO83M7jKzg+Hv+phzzjOz75jZo2b2sJn9fuTYLWb2fTN7MAznVZFHTCFFDMBZ6xC3TVGDbprBumvjtGiUrmder+o1tBO4xzl3DnBPuD/JS8AfOOfeAVwEfM7M3hQ5/ufOufPC8GBFecS0UXTkqk/zHdW1DoOZ3DGnnE48hSJUVQTbgL3h9l7gkskTnHNPOOcOhtv/AjwPbKz4XNF38vr75/WX94Xo/9q1C+bn87dQ4koDM7jqqmA7Kb3anphG1E7njdk4w0HeALwY2bbofsL57wIeB1aF+7cQLFr/MHAdsDbl2h3AMrC8efPmei0ool2KuEj0yW2xDtePotNcyJtnKmjLDk9ZryHgbuCRmLBtsuAHfpxyn01hof/uiTgD1hK0KP4iSx4nr6H+U6Rw71NB15TSSrtvnxSliKXN6axKK4K0EBbsm1ykoE8475eB/wtcmnKv9wP/lOe5UgQ9p6i/f1/cFpuagC3tvpr0rfek6fK660FJiqCqjWAfMB9uzwPfmDzBzNYAXwf+3jl3+8SxTeGvEdgXHqkoj+gDRVwkik6a1iVNuX6k3bdrdxNRmTQzWFuzfFdVBNcCHzKzg8CF4T5mNmdmN4Xn/B7wPuATMW6iS2a2H9gPbAD+sqI8og/kdZGoY2L2Ng2pTbl+pN23SFrKoOwlabq8NV+JuGaC70FdQ1NAnu6eOkYKt21faKobK+2+Wc/sk51lgKS9nrpNQGhksegdScMtITk+St45+6cdpYP3JPWA1j1YXusRxKDWsuekDbCqMrW0r2MQmkLp4D1J4yDH4wuiq6K+4Q31P3+wikBrbveA3buDQn8S5/JZy2RIDVA69J6XXz6xffRo/WXVYBWB1tzuAdu3J3cB5anNdj1uvwnKNGOnMR0GRBtl1WAVgVrLPWF2Nj4+T22283H7NVO2GTtt6TAw2iirBmsslv2sJ/g2tXSXKNMOkjpfu4zFE6i13BNUmz2BmrGDpI2yarCKQOVLj/BpaukukdF3kLRRVg1WEUBy+SK3UuElasZOHXnLmqbrQqvrvV3/meySHtvjYLgVUeEJ4wzYl7mXRCo+lTWDNRYnIXucEKINuihrZCzOiexxQog28KmskSKYQPY4IUQb+FTWSBFMIHucEKINfCprpAgmkFupEKINfCpr5DUUw/btKviFEM3g46J7lVoEZnaamd1lZgfD3/UJ5x2PrE62LxJ/lpndb2aHzOy2cFlLIYToBUXHHPk663HVrqGdwD3OuXOAe8L9OF52zp0Xhosj8X8NXOec+3fAj4ErK8ojhBCtUKZQ93XW46qKYBuwN9zeS7AAfS7CBes/CIwXtC90vRBCdEmZQj3LZbSrWQ2qKoI3O+eeC7d/CLw54bzXm9mymd1nZpeEcSPgRefcq+H+EeD0pAeZ2Y7wHssrKysVxRZCiGqUGQeQ5jLaZbdRpiIws7vN7JGYsC16XrgwctIw5dlwNNvHgc+Z2VuLCuqc2+Ocm3POzW3cuLHo5UIIUStlxgGkuYx22W2UqQiccxc65/5DTPgG8CMz2wQQ/j6fcI9nw9/DwL3A+cBR4E1mNvZcOgN4tvI/EkKIFigzDiDNZbTLkcZVu4b2AfPh9jzwjckTzGy9ma0NtzcAvw48FrYgvg1cmna9EEL4SN5xAJP9/hA/k2iXI42rKoJrgQ+Z2UHgwnAfM5szs5vCc94OLJvZQwQF/7XOucfCY58BPm1mhwhsBn9XUR4hhGiEOENu1vTQRfr9Ox1p7JzrXbjgggtcURYXnZuddc4s+F1cLHyLXPep6zlCiO4Zf88QfNNBcR6Edeuyv+/xtZNhdjb9eU2VH8CyiylTOy/Uy4SiimBxMXhp0Rdh5tzCQqHbxN4nmhmyjgsh+kPc95y3QB8zqTyi5U8XJCmCQaxHkDTvtxncemv+4d1Z84drLQMhpoek7zmKWdAtVPQeXZUJg16PIMnq7lwx16wsq75P84sLIaqR57vNMuQm9ftv3erXcriDUARpL6tIIZ1l1fdpfnEhRDWyvts8htw4z6L5edi716/5hgahCHbvDl5CHEUK6Syrvk/ziwshqhH3PY/LkSJTRk96Ft1xh4fzDcUZDnwPZbyGFhbSrf4LC87NzATxMzPJhmR5DQkxHJr4nrs0IDNkr6ExSS91YSH+xRT1KqoDKRIhpoOkb7moS2mdJCmCQXgNZbF6NRw/fmr8zAy8+uqp8U0xHnwSbTauW6cV0oToG2nfMnT3nQ/aayiLOCWQFt8Uvs5VLoTIJjryeH4++Vv2aYnKMWoR4E+LYNWqoJE4SZavshCiW+JaAHF0/S2rRZDCjh3F4ptC7qdC9JO41nwcvn7LUgTADTfAwkLQAoDgd2EhiB/TxspBcj8VohpdrfCVZzxS2rfcldy/IM6C7Hso6zVUljxzDNXl6SOvISHK0eVcX0meQFGPoCQ52pQbeQ2VJ22+kN275ekjhA90Oa/P0hJcfnn8MZ/mI0qyEUgR5CDNiLt5c/xLHI3ghReal00IEZD0nULwPR47Fnyvu3c3U0nbsAGOHj01PqtAb9NJpBFjsZmdZmZ3mdnB8Hd9zDkfMLMHI+FfxwvYm9ktZvb9yLHzqsjTFGlG3KS+waNHu59ISoghkWaIPXq0+Xl9rr++nI3PByeRqsbincA9zrlzgHvC/ZNwzn3bOXeec+484IPAS8D/iJzy5+PjzrkHK8rTCGlG3LSXJf9/Idoj7juNo6mxOWXHB3jhJBJnOMgbgAPApnB7E3Ag4/wdwFJk/xbg0qLPbdtY7FyyEXdxMdlAFDd3SPQ+o1EQZBgWoh7SvkcfFoZJoi0nEZqYawh4MbJt0f2E878F/KfI/i2hMnkYuA5Ym+e5XSiCNEajZE+BKFkrHjXp4SBvJDEUsjx4xhNLDvEbKK0IgLuBR2LCtsmCH/hxyn02ASvA6ybiDFgL7AX+IuX6HcAysLx58+YWkiw/ed2/8mTQJiae0hKaYkjkWWJyqN9AUy2C3F1DwH8F9qQcfz/wT3me61uLwLl8Ne6k6WebbrJ2OduhEF0w2QW7apW+AeeSFUFVY/E+YD7cnge+kXLux4AvRyPMbFP4a8AlBC2NXjK5+EScgSiPF0ATngJaQlP0gTpH10a/xxdeSHYr1TcQUFURXAt8yMwOAheG+5jZnJndND7JzLYAZwL/c+L6JTPbD+wHNgB/WVEer8nyamjKU8AH9zQh0hhP2tbU8o36BjKIayb4HnzsGspLF15DshEI36mj+zKte9b3b6DXXkNdhT4rgq6Q15DwmarLN+Yp6BcXT/bwG438+A4011BJ2p5iQgjRLFXn28lzva8rAJadmqIMWo9ACOEtVUfX5nGI8HEFwKWleCUA7RqypQiEEJ1TdfnGNGPw2BsprsUA3XoOpSmhPs01JGqi84UphKiJsnk5jwt2Ekktiq1bT3gjJdGl51CaEmpzriEpAg9o2nWuTaTQppO877WrvJzUorjjjvQlJLteATBJCY1GLdst4izIvodp8xqalpG/vrvoiXIUea++5eW00fw+eM+1/c0g91F/qeo65wu+FQKiHoq8V1/y8thduok5vep2xW7TtTtJEahrqEPGzW2X4MHbt1GPmspiOinyXn0YwRvtnoqjSndQE11fVWwjdSFF0BFNZtbJ57TVZ+9DISDqp8h77XqRlaUlmJ9PtgsU9UaaxEcX1FqIayb4Hqahayir2VpH87Dt/kfZCKaTou81b1dHE10sadNP19E95UvXV1mQjcAv2shQXfTZayqL6aSNQrtqpSFrvY868n3f7WBSBJ7RRobqe+1F1I8virqJ/J/mIVRXy7Tvrd4kRSAbQUe00ZeqPnu/aXvMhU/jVZpwLEjK1zMz9c0nVHUEtLfEaQffwzS0CJxrvnbW99rLNNPFu6lSC687rzbRIlB+zwZ1DU03SR9qnR9wW90KvnRfNEkXfc1luwqbKGCbKrSHkHeq0IgiAH4XeBR4DZhLOe8igvWNDwE7I/FnAfeH8bcBa/I8V4rgZNqoCaU9o25lM4RaXRf2m7LKpymlpUK7fZpSBG8HfhW4N0kRADPAk8DZwBrgIeDc8NhXgcvC7RuBhTzPlSI4mTZql0nPGI3qLbj77pWRl648usq8KzkdTA9JiqCSsdg597hz7kDGae8CDjnnDjvnfgZ8BdgWLlj/QeD28Ly9BAvYi4K0MaI36V5Hj9Y7wGYoo5O7GHhV1tApp4Pppw2vodOBZyL7R8K4EfCic+7VifhYzGyHmS2b2fLKykpjwvaRNj7UovcqW3APpdDpyvukzHQGXY8WFs2TqQjM7G4zeyQmbGtDwDHOuT3OuTnn3NzGjRvbfLT3tPGhJj1jNIo/v2zBPaRCx4c5ZvIwtS6T4heszjrBOXdhxWc8C5wZ2T8jjDsKvMnMVoetgnG8KMj4g9y1K6iJb94cFJx1fqhJz4D4dWDLFtxt/BdRnO3b9Q6mmVoWrzeze4E/c86dsqK8ma0GngB+k6Cg/x7wcefco2b2NeAfnHNfMbMbgYedczdkPU+L1/vF0pIKbiH6QCOL15vZb5vZEeA9wD+b2Z1h/FvM7A6AsLb/KeBO4HHgq865R8NbfAb4tJkdIrAZ/F0VeUQ39KWLQwgRTy0tgrZRi0AIIYrTSItACCFE/5EiEEKIgSNFIIQQA0eKQAghBk4vjcVmtgIkrPabygbghZrFqQPJVRxfZZNcxfFVtmmUa9Y5d8qI3F4qgrKY2XKcxbxrJFdxfJVNchXHV9mGJJe6hoQQYuBIEQghxMAZmiLY07UACUiu4vgqm+Qqjq+yDUauQdkIhBBCnMrQWgRCCCEmkCIQQoiBM3WKwMx+18weNbPXzCzRxcrMLjKzA2Z2yMx2RuLPMrP7w/jbzGxNTXKdZmZ3mdnB8Hd9zDkfMLMHI+FfzeyS8NgtZvb9yLHz2pIrPO945Nn7IvGNpFde2czsPDP7TvjOHzaz348cqzXNkvJM5PjaMA0OhWmyJXLs6jD+gJl9pIocJeT6tJk9FqbPPWY2GzkW+15bkusTZrYSef4fRY7Nh+/9oJnN1ylXTtmui8j1hJm9GDnWSJqZ2c1m9ryZPZJw3Mzsb0OZHzazd0aOVUuvuIWM+xyAtwO/CtwLzCWcMwM8CZwNrAEeAs4Nj30VuCzcvhFYqEmuvwF2hts7gb/OOP804BiwLty/Bbi0gfTKJRfw04T4RtIrr2zAvwfOCbffAjwHvKnuNEvLM5Fz/hi4Mdy+DLgt3D43PH8tcFZ4n5kW5fpAJB8tjOVKe68tyfUJ4PMx154GHA5/14fb69uUbeL8PwVubiHN3ge8E3gk4fhW4JuAAe8G7q8rvaauReCce9w5dyDjtHcBh5xzh51zPwO+AmwzMwM+CNwenrcXuKQm0baF98t730uBbzrnXso4rypF5foFDadXLtmcc0845w6G2/8CPA80sZZpbJ5Jkfd24DfDNNoGfMU594pz7vvAofB+rcjlnPt2JB/dR7AaYNPkSa8kPgLc5Zw75pz7MXAXcFGHsn0M+HKNz4/FOfe/CCp/SWwD/t4F3EewwuMmakivqVMEOTkdeCayfySMGwEvumAxnWh8HbzZOfdcuP1D4M0Z51/GqZlvd9gkvM7M1rYs1+vNbNnM7ht3V9FsehWRDQAzexdBDe/JSHRdaZaUZ2LPCdPkJwRplOfaJuWKciVBrXJM3HttU67fCd/P7WY2XtK2yfQqdP+wG+0s4FuR6KbSLIskuSunV+aaxT5iZncD/zbm0C7n3DfalmdMmlzRHeecM7NEv91Qy/9HglXdxlxNUBiuIfAj/gxwTYtyzTrnnjWzs4Fvmdl+goKuEjWn2a3AvHPutTC6dJpNI2Z2OTAH/EYk+pT36px7Mv4OtfOPwJedc6+Y2X8maE19sKVn5+Uy4Hbn3PFIXJdp1gi9VATOuQsr3uJZ4MzI/hlh3FGC5tbqsEY3jq8sl5n9yMw2OeeeCwut51Nu9XvA151zP4/ce1wzfsXMvgT8WZtyOeeeDX8PW7BG9fnAP1AhveqSzcx+GfhngorAfZF7l06zGJLyTNw5RyxYq/tXCPJUnmublAszu5BAuf6Gc+6VcXzCe62jUMuUyzl3NLJ7E4FNaHzt+yeuvbcGmXLLFuEy4E+iEQ2mWRZJcldOr6F2DX0POMcCj5c1BC97nwssL98m6J8HmAfqamHsC++X576n9EmGBeG4X/4SINazoAm5zGz9uFvFzDYAvw481nB65ZVtDfB1gr7T2yeO1ZlmsXkmRd5LgW+FabQPuMwCr6KzgHOA71aQpZBcZnY+8EXgYufc85H42PfaolybIrsXE6xpDkFL+MOhfOuBD3Ny67hx2UL53kZgfP1OJK7JNMtiH/AHoffQu4GfhJWd6unVhPW7ywD8NkEf2SvAj4A7w/i3AHdEztsKPEGgyXdF4s8m+EgPAV8D1tYk1wi4BzgI3A2cFsbPATdFzttCoOFXTVz/LWA/QWG2CLyxLbmA94bPfij8vbLp9Cog2+XAz4EHI+G8JtIsLs8QdDVdHG6/PkyDQ2GanB25dld43QHgozXn+Sy57g6/hXH67Mt6ry3J9VfAo+Hzvw28LXLtH4bpeAj4ZJ1y5ZEt3P8scO3EdY2lGUHl77kwPx8hsOdcBVwVHjfgC6HM+4l4RVZNL00xIYQQA2eoXUNCCCFCpAiEEGLgSBEIIcTAkSIQQoiBI0UghBADR4pACCEGjhSBEEIMnP8PNRUZ2fYpuekAAAAASUVORK5CYII=",
"text/plain": [ "text/plain": [
"<Figure size 432x288 with 1 Axes>" "<Figure size 432x288 with 1 Axes>"
] ]
...@@ -264,7 +274,7 @@ ...@@ -264,7 +274,7 @@
}, },
{ {
"data": { "data": {
"image/png": "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", "image/png": "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",
"text/plain": [ "text/plain": [
"<Figure size 432x288 with 1 Axes>" "<Figure size 432x288 with 1 Axes>"
] ]
...@@ -284,12 +294,6 @@ ...@@ -284,12 +294,6 @@
} }
], ],
"source": [ "source": [
"# 数据集参数设置\n",
"Ntrain = 200 # 规定训练集大小\n",
"Ntest = 100 # 规定测试集大小\n",
"boundary_gap = 0.5 # 设置决策边界的宽度\n",
"seed_data = 2 # 固定随机种子\n",
"\n",
"# 生成自己的数据集\n", "# 生成自己的数据集\n",
"train_x, train_y, test_x, test_y = circle_data_point_generator(Ntrain, Ntest, boundary_gap, seed_data)\n", "train_x, train_y, test_x, test_y = circle_data_point_generator(Ntrain, Ntest, boundary_gap, seed_data)\n",
"\n", "\n",
...@@ -434,7 +438,7 @@ ...@@ -434,7 +438,7 @@
}, },
"outputs": [], "outputs": [],
"source": [ "source": [
"# 构建绕Y轴,绕Z轴旋转theta角度矩阵\n", "# 构建绕 Y 轴,绕 Z 轴旋转 theta 角度矩阵\n",
"def Ry(theta):\n", "def Ry(theta):\n",
" \"\"\"\n", " \"\"\"\n",
" :param theta: 参数\n", " :param theta: 参数\n",
...@@ -466,20 +470,20 @@ ...@@ -466,20 +470,20 @@
" zero_state = np.array([[1, 0]])\n", " zero_state = np.array([[1, 0]])\n",
" # 角度编码\n", " # 角度编码\n",
" for i in range(n_qubits):\n", " for i in range(n_qubits):\n",
" # 对偶数编号量子态作用Rz(arccos(x0^2)) Ry(arcsin(x0))\n", " # 对偶数编号量子态作用 Rz(arccos(x0^2)) Ry(arcsin(x0))\n",
" if i % 2 == 0:\n", " if i % 2 == 0:\n",
" state_tmp=np.dot(zero_state, Ry(np.arcsin(data[sam][0])).T)\n", " state_tmp=np.dot(zero_state, Ry(np.arcsin(data[sam][0])).T)\n",
" state_tmp=np.dot(state_tmp, Rz(np.arccos(data[sam][0] ** 2)).T)\n", " state_tmp=np.dot(state_tmp, Rz(np.arccos(data[sam][0] ** 2)).T)\n",
" res_state=np.kron(res_state, state_tmp)\n", " res_state=np.kron(res_state, state_tmp)\n",
" # 对奇数编号量子态作用Rz(arccos(x1^2)) Ry(arcsin(x1))\n", " # 对奇数编号量子态作用 Rz(arccos(x1^2)) Ry(arcsin(x1))\n",
" elif i % 2 == 1:\n", " elif i % 2 == 1:\n",
" state_tmp=np.dot(zero_state, Ry(np.arcsin(data[sam][1])).T)\n", " state_tmp=np.dot(zero_state, Ry(np.arcsin(data[sam][1])).T)\n",
" state_tmp=np.dot(state_tmp, Rz(np.arccos(data[sam][1] ** 2)).T)\n", " state_tmp=np.dot(state_tmp, Rz(np.arccos(data[sam][1] ** 2)).T)\n",
" res_state=np.kron(res_state, state_tmp)\n", " res_state=np.kron(res_state, state_tmp)\n",
" res.append(res_state)\n", " res.append(res_state)\n",
"\n",
" res = np.array(res)\n", " res = np.array(res)\n",
" return res.astype(\"complex128\")\n" "\n",
" return res.astype(\"complex128\")"
] ]
}, },
{ {
...@@ -573,7 +577,7 @@ ...@@ -573,7 +577,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 8, "execution_count": 13,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-03-02T09:15:06.795398Z", "end_time": "2021-03-02T09:15:06.795398Z",
...@@ -592,7 +596,7 @@ ...@@ -592,7 +596,7 @@
" \"\"\"\n", " \"\"\"\n",
" # 初始化网络\n", " # 初始化网络\n",
" cir = UAnsatz(n)\n", " cir = UAnsatz(n)\n",
" \n", "\n",
" # 先搭建广义的旋转层\n", " # 先搭建广义的旋转层\n",
" for i in range(n):\n", " for i in range(n):\n",
" cir.rz(theta[i][0], i)\n", " cir.rz(theta[i][0], i)\n",
...@@ -699,7 +703,7 @@ ...@@ -699,7 +703,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 9, "execution_count": 8,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-03-02T09:15:07.667491Z", "end_time": "2021-03-02T09:15:07.667491Z",
...@@ -716,12 +720,13 @@ ...@@ -716,12 +720,13 @@
" :return: 局部可观测量: Z \\otimes I \\otimes ...\\otimes I\n", " :return: 局部可观测量: Z \\otimes I \\otimes ...\\otimes I\n",
" \"\"\"\n", " \"\"\"\n",
" Ob = pauli_str_to_matrix([[1.0, 'z0']], n)\n", " Ob = pauli_str_to_matrix([[1.0, 'z0']], n)\n",
"\n",
" return Ob" " return Ob"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 10, "execution_count": 9,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
...@@ -735,7 +740,6 @@ ...@@ -735,7 +740,6 @@
" super(Opt_Classifier, self).__init__()\n", " super(Opt_Classifier, self).__init__()\n",
" self.n = n\n", " self.n = n\n",
" self.depth = depth\n", " self.depth = depth\n",
" \n",
" # 初始化参数列表 theta,并用 [0, 2*pi] 的均匀分布来填充初始值\n", " # 初始化参数列表 theta,并用 [0, 2*pi] 的均匀分布来填充初始值\n",
" self.theta = self.create_parameter(\n", " self.theta = self.create_parameter(\n",
" shape=[n, depth + 3], # 此处使用量子电路有初始一层广义旋转门,故+3\n", " shape=[n, depth + 3], # 此处使用量子电路有初始一层广义旋转门,故+3\n",
...@@ -759,22 +763,22 @@ ...@@ -759,22 +763,22 @@
" \"\"\"\n", " \"\"\"\n",
" # 将 Numpy array 转换成 tensor\n", " # 将 Numpy array 转换成 tensor\n",
" Ob = paddle.to_tensor(Observable(self.n))\n", " Ob = paddle.to_tensor(Observable(self.n))\n",
" label_pp = paddle.to_tensor(label)\n", " label_pp = reshape(paddle.to_tensor(label), [-1, 1])\n",
"\n", "\n",
" # 按照随机初始化的参数 theta \n", " # 按照随机初始化的参数 theta \n",
" cir = cir_Classifier(self.theta, n=self.n, depth=self.depth)\n", " cir = cir_Classifier(self.theta, n=self.n, depth=self.depth)\n",
" Utheta = cir.U\n", " Utheta = cir.U\n",
" \n", "\n",
" # 因为 Utheta是学习到的,我们这里用行向量运算来提速而不会影响训练效果\n", " # 因为 Utheta是学习到的,我们这里用行向量运算来提速而不会影响训练效果\n",
" state_out = matmul(state_in, Utheta) # [-1, 1, 2 ** n]形式,第一个参数在此教程中为BATCH\n", " state_out = matmul(state_in, Utheta) # [-1, 1, 2 ** n]形式,第一个参数在此教程中为BATCH\n",
" \n", "\n",
" # 测量得到泡利 Z 算符的期望值 <Z> -- shape [-1,1,1]\n", " # 测量得到泡利 Z 算符的期望值 <Z> -- shape [-1,1,1]\n",
" E_Z = matmul(matmul(state_out, Ob), transpose(paddle.conj(state_out), perm=[0, 2, 1]))\n", " E_Z = matmul(matmul(state_out, Ob), transpose(paddle.conj(state_out), perm=[0, 2, 1]))\n",
" \n", "\n",
" # 映射 <Z> 处理成标签的估计值 \n", " # 映射 <Z> 处理成标签的估计值 \n",
" state_predict = paddle.real(E_Z)[:, 0] * 0.5 + 0.5 + self.bias # 计算每一个y^{i,k}与真实值得平方差\n", " state_predict = paddle.real(E_Z)[:, 0] * 0.5 + 0.5 + self.bias # 计算每一个y^{i,k}与真实值得平方差\n",
" loss = paddle.mean((state_predict - label_pp) ** 2) # 对BATCH个得到的平方差取平均,得到L_i:shape:[1,1]\n", " loss = paddle.mean((state_predict - label_pp) ** 2) # 对BATCH个得到的平方差取平均,得到L_i:shape:[1,1]\n",
" \n", "\n",
" # 计算交叉验证正确率\n", " # 计算交叉验证正确率\n",
" is_correct = (paddle.abs(state_predict - label_pp) < 0.5).nonzero().shape[0]\n", " is_correct = (paddle.abs(state_predict - label_pp) < 0.5).nonzero().shape[0]\n",
" acc = is_correct / label.shape[0]\n", " acc = is_correct / label.shape[0]\n",
...@@ -842,7 +846,7 @@ ...@@ -842,7 +846,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"def QClassifier(Ntrain, Ntest, gap, N, DEPTH, EPOCH, LR, BATCH, seed_paras, seed_data,):\n", "def QClassifier(Ntrain, Ntest, gap, N, DEPTH, EPOCH, LR, BATCH, seed_paras, seed_data):\n",
" \"\"\"\n", " \"\"\"\n",
" 量子二分类器\n", " 量子二分类器\n",
" 输入参数:\n", " 输入参数:\n",
...@@ -861,7 +865,7 @@ ...@@ -861,7 +865,7 @@
" train_x, train_y, test_x, test_y = circle_data_point_generator(Ntrain=Ntrain, Ntest=Ntest, boundary_gap=gap, seed_data=seed_data)\n", " train_x, train_y, test_x, test_y = circle_data_point_generator(Ntrain=Ntrain, Ntest=Ntest, boundary_gap=gap, seed_data=seed_data)\n",
" # 读取训练集的维度\n", " # 读取训练集的维度\n",
" N_train = train_x.shape[0]\n", " N_train = train_x.shape[0]\n",
" \n", "\n",
" paddle.seed(seed_paras)\n", " paddle.seed(seed_paras)\n",
" # 初始化寄存器存储正确率 acc 等信息\n", " # 初始化寄存器存储正确率 acc 等信息\n",
" summary_iter, summary_test_acc = [], []\n", " summary_iter, summary_test_acc = [], []\n",
...@@ -904,7 +908,7 @@ ...@@ -904,7 +908,7 @@
" loss.backward()\n", " loss.backward()\n",
" opt.minimize(loss)\n", " opt.minimize(loss)\n",
" opt.clear_grad()\n", " opt.clear_grad()\n",
" \n", "\n",
" # 得到训练后电路\n", " # 得到训练后电路\n",
" print(\"训练后的电路:\")\n", " print(\"训练后的电路:\")\n",
" print(cir)\n", " print(cir)\n",
...@@ -960,7 +964,7 @@ ...@@ -960,7 +964,7 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"主程序段总共运行了 7.24103569984436 秒\n" "主程序段总共运行了 6.890974283218384 秒\n"
] ]
} }
], ],
...@@ -998,6 +1002,379 @@ ...@@ -998,6 +1002,379 @@
"通过打印训练结果可以看到不断优化后分类器在测试集和数据集的正确率都达到了 $100\\%$。" "通过打印训练结果可以看到不断优化后分类器在测试集和数据集的正确率都达到了 $100\\%$。"
] ]
}, },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 研究不同的编码方式\n",
"\n",
"监督学习的编码方式对分类结果有很大影响 [4]。在量桨中,我们集成了常用的编码方式,包括振幅编码、角度编码、IQP编码等。 用户可以用内置的 ``SimpleDataset`` 类实例对简单分类数据(不需要降维的数据)进行编码;也可以用内置的 ``VisionDataset`` 类实例对图片数据进行编码。编码的方法都是调用类对象的 ``encode`` 方法。"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'numpy.ndarray'>\n",
"(100, 4)\n"
]
}
],
"source": [
"# 使用前面构建的圆形数据集研究编码\n",
"from paddle_quantum.dataset import *\n",
"\n",
"# 用两个量子比特编码二维数据\n",
"quantum_train_x = SimpleDataset(2).encode(train_x, 'angle_encoding', 2)\n",
"quantum_test_x = SimpleDataset(2).encode(test_x, 'angle_encoding', 2)\n",
"\n",
"print(type(quantum_test_x)) # ndarray\n",
"print(quantum_test_x.shape) # (100, 4)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"这里我们对上面的分类器进行化简,之后的所有分类都采用这个分类器。"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [],
"source": [
"# 简化的分类器\n",
"def QClassifier2(quantum_train_x, train_y,quantum_test_x,test_y, N, DEPTH, EPOCH, LR, BATCH):\n",
" \"\"\"\n",
" 量子二分类分类器\n",
" 输入:\n",
" quantum_train_x # 训练特征\n",
" train_y # 训练标签\n",
" quantum_test_x # 测试特征\n",
" test_y # 测试标签\n",
" N # 使用的量子比特数目\n",
" DEPTH # 分类器电路的深度\n",
" EPOCH # 迭代次数\n",
" LR # 学习率\n",
" BATCH # 一个批量的大小\n",
" \"\"\"\n",
" Ntrain = len(quantum_train_x)\n",
" \n",
" paddle.seed(1)\n",
"\n",
" net = Opt_Classifier(n=N, depth=DEPTH)\n",
"\n",
" # 测试准确率列表\n",
" summary_iter, summary_test_acc = [], []\n",
"\n",
" # 这里用 Adam,但是也可以是 SGD 或者 RMSprop\n",
" opt = paddle.optimizer.Adam(learning_rate=LR, parameters=net.parameters())\n",
"\n",
" # 进行优化\n",
" for ep in range(EPOCH):\n",
" for itr in range(Ntrain // BATCH):\n",
" # 导入数据\n",
" input_state = quantum_train_x[itr * BATCH:(itr + 1) * BATCH] # paddle.tensor类型\n",
" input_state = reshape(input_state, [-1, 1, 2 ** N])\n",
" label = train_y[itr * BATCH:(itr + 1) * BATCH]\n",
" test_input_state = reshape(quantum_test_x, [-1, 1, 2 ** N])\n",
"\n",
" loss, train_acc, state_predict_useless, cir = net(state_in=input_state, label=label)\n",
"\n",
" if itr % 5 == 0:\n",
" # 获取测试准确率\n",
" loss_useless, test_acc, state_predict_useless, t_cir = net(state_in=test_input_state, label=test_y)\n",
" print(\"epoch:\", ep, \"iter:\", itr,\n",
" \"loss: %.4f\" % loss.numpy(),\n",
" \"train acc: %.4f\" % train_acc,\n",
" \"test acc: %.4f\" % test_acc)\n",
" summary_test_acc.append(test_acc)\n",
"\n",
" loss.backward()\n",
" opt.minimize(loss)\n",
" opt.clear_grad()\n",
"\n",
" return summary_test_acc"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"现在可以开始用不同编码方式对上面产生的圆形数据进行编码。这里我们采用五种编码方法:振幅编码、角度编码、泡利旋转编码、IQP编码、复杂纠缠编码。然后我们绘制出测试精度曲线以便分析。"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Encoding method: amplitude_encoding\n",
"epoch: 0 iter: 0 loss: 0.3066 train acc: 0.4000 test acc: 0.5400\n",
"epoch: 0 iter: 5 loss: 0.2378 train acc: 0.7000 test acc: 0.7000\n",
"epoch: 0 iter: 10 loss: 0.2308 train acc: 0.8000 test acc: 0.6700\n",
"epoch: 0 iter: 15 loss: 0.2230 train acc: 0.8000 test acc: 0.6100\n",
"Encoding method: angle_encoding\n",
"epoch: 0 iter: 0 loss: 0.2949 train acc: 0.5000 test acc: 0.3600\n",
"epoch: 0 iter: 5 loss: 0.1770 train acc: 0.7000 test acc: 0.7000\n",
"epoch: 0 iter: 10 loss: 0.1654 train acc: 0.8000 test acc: 0.7000\n",
"epoch: 0 iter: 15 loss: 0.1966 train acc: 0.7000 test acc: 0.5800\n",
"Encoding method: pauli_rotation_encoding\n",
"epoch: 0 iter: 0 loss: 0.2433 train acc: 0.6000 test acc: 0.7000\n",
"epoch: 0 iter: 5 loss: 0.2142 train acc: 0.7000 test acc: 0.7000\n",
"epoch: 0 iter: 10 loss: 0.2148 train acc: 0.7000 test acc: 0.7000\n",
"epoch: 0 iter: 15 loss: 0.2019 train acc: 0.8000 test acc: 0.7600\n",
"Encoding method: IQP_encoding\n",
"epoch: 0 iter: 0 loss: 0.2760 train acc: 0.6000 test acc: 0.4200\n",
"epoch: 0 iter: 5 loss: 0.1916 train acc: 0.6000 test acc: 0.6200\n",
"epoch: 0 iter: 10 loss: 0.1355 train acc: 0.9000 test acc: 0.7300\n",
"epoch: 0 iter: 15 loss: 0.1289 train acc: 0.9000 test acc: 0.6700\n",
"Encoding method: complex_entangled_encoding\n",
"epoch: 0 iter: 0 loss: 0.3274 train acc: 0.3000 test acc: 0.2900\n",
"epoch: 0 iter: 5 loss: 0.2120 train acc: 0.7000 test acc: 0.7000\n",
"epoch: 0 iter: 10 loss: 0.2237 train acc: 0.7000 test acc: 0.7000\n",
"epoch: 0 iter: 15 loss: 0.2095 train acc: 0.8000 test acc: 0.7200\n"
]
}
],
"source": [
"# 测试不同编码方式\n",
"encoding_list = ['amplitude_encoding', 'angle_encoding', 'pauli_rotation_encoding', 'IQP_encoding', 'complex_entangled_encoding']\n",
"num_qubit = 2 # 这里需要小心,如果量子比特数目取 1,可能会报错,因为有 CNOT 门\n",
"dimension = 2\n",
"acc_list = []\n",
"\n",
"for i in range(len(encoding_list)):\n",
" encoding = encoding_list[i]\n",
" print(\"Encoding method:\", encoding)\n",
" # 用 SimpleDataset 类来编码数据,这里数据维度为 2,编码量子比特数目也是 2\n",
" quantum_train_x= SimpleDataset(dimension).encode(train_x, encoding, num_qubit)\n",
" quantum_test_x= SimpleDataset(dimension).encode(test_x, encoding, num_qubit)\n",
" quantum_train_x = paddle.to_tensor(quantum_train_x)\n",
" quantum_test_x = paddle.to_tensor(quantum_test_x)\n",
"\n",
" acc = QClassifier2(\n",
" quantum_train_x, # 训练特征\n",
" train_y, # 训练标签\n",
" quantum_test_x, # 测试特征\n",
" test_y, # 测试标签\n",
" N = num_qubit, # 使用的量子比特数目\n",
" DEPTH = 1, # 分类器电路的深度\n",
" EPOCH = 1, # 迭代次数\n",
" LR = 0.1, # 学习率\n",
" BATCH = 10, # 一个批量的大小\n",
" )\n",
" acc_list.append(acc)"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# 绘制五种编码方法的训练曲线\n",
"x=[2*i for i in range(len(acc_list[0]))]\n",
"for i in range(len(encoding_list)):\n",
" plt.plot(x,acc_list[i])\n",
"plt.legend(encoding_list)\n",
"plt.title(\"Benchmarking different encoding methods\")\n",
"plt.xlabel(\"Iteration\")\n",
"plt.ylabel(\"Test accuracy\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 用内置的 MNIST 和 Iris 数据集实现量子分类\n",
"\n",
"量桨将常用的分类数据集进行了编码,用户可以使用 `paddle_quantum.dataset` 模块获取编码的量子电路或者量子态。目前集成了4个数据集,包括 MNIST, FashionMNIST, Iris 和 BreastCancer。下面展示如何用这些内置数据集快速实现量子监督学习。\n",
"\n",
"我们从 Iris 数据集开始。Iris 数据集包括三种类别,每种类别有50个样本。数据集中只有四个特征,是比较简单且容易编码的数据集。"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"epoch: 0 iter: 0 loss: 0.3543 train acc: 0.0000 test acc: 0.0000\n",
"epoch: 0 iter: 5 loss: 0.2697 train acc: 0.5000 test acc: 0.5000\n",
"epoch: 0 iter: 10 loss: 0.2139 train acc: 1.0000 test acc: 0.9000\n",
"epoch: 0 iter: 15 loss: 0.1989 train acc: 0.7500 test acc: 0.9000\n",
"epoch: 1 iter: 0 loss: 0.0859 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 1 iter: 5 loss: 0.0432 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 1 iter: 10 loss: 0.0432 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 1 iter: 15 loss: 0.0531 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 2 iter: 0 loss: 0.0374 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 2 iter: 5 loss: 0.0356 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 2 iter: 10 loss: 0.0377 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 2 iter: 15 loss: 0.0440 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 3 iter: 0 loss: 0.0317 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 3 iter: 5 loss: 0.0344 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 3 iter: 10 loss: 0.0384 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 3 iter: 15 loss: 0.0412 train acc: 1.0000 test acc: 1.0000\n"
]
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# Iris 数据集二分类\n",
"\n",
"test_rate=0.2\n",
"num_qubit=4\n",
"\n",
"# 获取 Iris 数据集的量子态\n",
"iris =Iris (encoding='angle_encoding', num_qubits=num_qubit, test_rate=test_rate,classes=[0, 1], return_state=True)\n",
"\n",
"quantum_train_x, train_y = iris.train_x, iris.train_y\n",
"quantum_test_x, test_y = iris.test_x, iris.test_y\n",
"testing_data_num = len(test_y)\n",
"training_data_num = len(train_y)\n",
"\n",
"acc = QClassifier2(\n",
" quantum_train_x, # 训练特征\n",
" train_y, # 训练标签\n",
" quantum_test_x, # 测试特征\n",
" test_y, # 测试标签\n",
" N = num_qubit, # 使用的量子比特数目\n",
" DEPTH = 1, # 分类器电路的深度\n",
" EPOCH = 4, # 迭代次数\n",
" LR = 0.1, # 学习率\n",
" BATCH = 4, # 一个批量的大小\n",
" )\n",
"plt.plot(acc)\n",
"plt.title(\"Classify Iris 0&1 using angle encoding\")\n",
"plt.xlabel(\"Iteration\")\n",
"plt.ylabel(\"Testing accuracy\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"第二个例子为 MNIST 数据集。 MNIST 是手写数字数据集,有 0-9 十个类别(每一类训练集中有 6000 个样本,测试集中有 1000 个样本)。所有的图片都是 $28\\times28$ 的灰度图,所以需要使用 ``resize`` 或 ``PCA`` 降维到目标维度 ``target_dimension`` 。"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"epoch: 0 iter: 0 loss: 0.3237 train acc: 0.3250 test acc: 0.5450\n",
"epoch: 0 iter: 5 loss: 0.2124 train acc: 0.7500 test acc: 0.6500\n",
"epoch: 0 iter: 10 loss: 0.2294 train acc: 0.6500 test acc: 0.6850\n",
"epoch: 1 iter: 0 loss: 0.1970 train acc: 0.7250 test acc: 0.7850\n",
"epoch: 1 iter: 5 loss: 0.1521 train acc: 0.8500 test acc: 0.8150\n",
"epoch: 1 iter: 10 loss: 0.1726 train acc: 0.7750 test acc: 0.8900\n",
"epoch: 2 iter: 0 loss: 0.1742 train acc: 0.7250 test acc: 0.8650\n",
"epoch: 2 iter: 5 loss: 0.1167 train acc: 0.9000 test acc: 0.8900\n",
"epoch: 2 iter: 10 loss: 0.1654 train acc: 0.8000 test acc: 0.8950\n",
"epoch: 3 iter: 0 loss: 0.1609 train acc: 0.8000 test acc: 0.8850\n",
"epoch: 3 iter: 5 loss: 0.1148 train acc: 0.9250 test acc: 0.8850\n",
"epoch: 3 iter: 10 loss: 0.1649 train acc: 0.8000 test acc: 0.8750\n",
"epoch: 4 iter: 0 loss: 0.1629 train acc: 0.8250 test acc: 0.8750\n",
"epoch: 4 iter: 5 loss: 0.1112 train acc: 0.9000 test acc: 0.8700\n",
"epoch: 4 iter: 10 loss: 0.1630 train acc: 0.8500 test acc: 0.8850\n"
]
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# 使用 MNIST 进行分类\n",
"\n",
"# 主要参数\n",
"training_data_num = 500\n",
"testing_data_num = 200\n",
"qubit_num = 4\n",
"\n",
"# 选择3和6两个类,将 MNIST 从 28*28 重采样为 4*4,再用振幅编码方式进行编码 \n",
"train_dataset = MNIST(mode='train', encoding='amplitude_encoding', num_qubits=qubit_num, classes=[3,6],\n",
" data_num=training_data_num,need_cropping=True,\n",
" downscaling_method='resize', target_dimension=16, return_state=True)\n",
"\n",
"val_dataset = MNIST(mode='test', encoding='amplitude_encoding', num_qubits=qubit_num, classes=[3,6],\n",
" data_num=testing_data_num,need_cropping=True,\n",
" downscaling_method='resize', target_dimension=16,return_state=True)\n",
"\n",
"quantum_train_x, train_y = train_dataset.quantum_image_states, train_dataset.labels\n",
"quantum_test_x, test_y = val_dataset.quantum_image_states, val_dataset.labels\n",
"\n",
"acc = QClassifier2(\n",
" quantum_train_x, # 训练特征\n",
" train_y, # 训练标签\n",
" quantum_test_x, # 测试特征\n",
" test_y, # 测试标签\n",
" N = num_qubit, # 使用的量子比特数目\n",
" DEPTH = 3, # 分类器电路的深度\n",
" EPOCH = 5, # 迭代次数\n",
" LR = 0.1, # 学习率\n",
" BATCH = 40, # 一个批量的大小\n",
" )\n",
"plt.plot(acc)\n",
"plt.title(\"Classify MNIST 3&6 using amplitude encoding\")\n",
"plt.xlabel(\"Iteration\")\n",
"plt.ylabel(\"Testing accuracy\")\n",
"plt.show()"
]
},
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
...@@ -1010,7 +1387,9 @@ ...@@ -1010,7 +1387,9 @@
"\n", "\n",
"[2] Farhi, Edward, and Hartmut Neven. Classification with quantum neural networks on near term processors. [arXiv preprint arXiv:1802.06002 (2018).](https://arxiv.org/abs/1802.06002)\n", "[2] Farhi, Edward, and Hartmut Neven. Classification with quantum neural networks on near term processors. [arXiv preprint arXiv:1802.06002 (2018).](https://arxiv.org/abs/1802.06002)\n",
"\n", "\n",
"[3] Schuld, Maria, et al. Circuit-centric quantum classifiers. [Physical Review A 101.3 (2020): 032308.](https://arxiv.org/abs/1804.00633)" "[3] Schuld, Maria, et al. Circuit-centric quantum classifiers. [Physical Review A 101.3 (2020): 032308.](https://arxiv.org/abs/1804.00633)\n",
"\n",
"[4] Schuld, Maria. Supervised quantum machine learning models are kernel methods. [arXiv preprint arXiv:2101.11020 (2021).](https://arxiv.org/pdf/2101.11020)"
] ]
} }
], ],
...@@ -1030,7 +1409,7 @@ ...@@ -1030,7 +1409,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.7.11" "version": "3.8.12"
}, },
"toc": { "toc": {
"base_numbering": 1, "base_numbering": 1,
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
"source": [ "source": [
"## Overview\n", "## Overview\n",
"\n", "\n",
"In this tutorial, we will discuss the workflow of Variational Quantum Classifiers (VQC) and how to use quantum neural networks (QNN) to accomplish a **binary classification** task. The main representatives of this approach include the [Quantum Circuit Learning (QCL)](https://arxiv.org/abs/1803.00745) [1] by Mitarai et al. (2018), Farhi & Neven ( 2018) [2] and [Circuit-Centric Quantum Classifiers](https://arxiv.org/abs/1804.00633) [3] by Schuld et al. (2018). Here, we mainly talk about classification in the language of supervised learning. Unlike classical methods, quantum classifiers require pre-processing to encode classical data into quantum data, and then train the parameters in the quantum neural network. Finally, we benchmark the optimal classification performance through test data.\n", "In this tutorial, we will discuss the workflow of Variational Quantum Classifiers (VQC) and how to use quantum neural networks (QNN) to accomplish a **binary classification** task. The main representatives of this approach include the [Quantum Circuit Learning (QCL)](https://arxiv.org/abs/1803.00745) [1] by Mitarai et al. (2018), Farhi & Neven (2018) [2] and [Circuit-Centric Quantum Classifiers](https://arxiv.org/abs/1804.00633) [3] by Schuld et al. (2018). Here, we mainly talk about classification in the language of supervised learning. Unlike classical methods, quantum classifiers require pre-processing to encode classical data into quantum data, and then train the parameters in the quantum neural network. Using different encoding methods, we can benchmark the optimal classification performance through test data. Finally, we demonstrate how to use built-in quantum datasets to accomplish quantum classification.\n",
"\n", "\n",
"### Background\n", "### Background\n",
"\n", "\n",
...@@ -53,7 +53,16 @@ ...@@ -53,7 +53,16 @@
"cell_type": "code", "cell_type": "code",
"execution_count": 1, "execution_count": 1,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\Users\\yeruilin\\Anaconda3\\envs\\paddle_quantum_env\\lib\\site-packages\\matplotlib_inline\\config.py:66: DeprecationWarning: InlineBackend._figure_formats_changed is deprecated in traitlets 4.1: use @observe and @unobserve instead.\n",
" def _figure_formats_changed(self, name, old, new):\n"
]
}
],
"source": [ "source": [
"# Import numpy and paddle\n", "# Import numpy and paddle\n",
"import numpy as np\n", "import numpy as np\n",
...@@ -63,8 +72,8 @@ ...@@ -63,8 +72,8 @@
"from paddle_quantum.circuit import UAnsatz\n", "from paddle_quantum.circuit import UAnsatz\n",
"# Some functions\n", "# Some functions\n",
"from numpy import pi as PI\n", "from numpy import pi as PI\n",
"from paddle import matmul, transpose # paddle matrix multiplication and transpose\n", "from paddle import matmul, transpose, reshape # paddle matrix multiplication and transpose\n",
"from paddle_quantum.utils import pauli_str_to_matrix,dagger # N qubits Pauli matrix, complex conjugate\n", "from paddle_quantum.utils import pauli_str_to_matrix, dagger # N qubits Pauli matrix, complex conjugate\n",
"\n", "\n",
"# Plot figures, calculate the run time\n", "# Plot figures, calculate the run time\n",
"from matplotlib import pyplot as plt\n", "from matplotlib import pyplot as plt\n",
...@@ -84,17 +93,19 @@ ...@@ -84,17 +93,19 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"Ntrain = 200 # Specify the training set size\n", "# Parameters for generating the data set\n",
"Ntest = 100 # Specify the test set size\n", "Ntrain = 200 # Specify the training set size\n",
"gap = 0.5 # Set the width of the decision boundary\n", "Ntest = 100 # Specify the test set size\n",
"N = 4 # Number of qubits required\n", "boundary_gap = 0.5 # Set the width of the decision boundary\n",
"DEPTH = 1 # Circuit depth\n", "seed_data = 2 # Fixed random seed required to generate the data set\n",
"BATCH = 20 # Batch size during training\n", "# Parameters for training\n",
"N = 4 # Number of qubits required\n",
"DEPTH = 1 # Circuit depth\n",
"BATCH = 20 # Batch size during training\n",
"EPOCH = int(200 * BATCH / Ntrain)\n", "EPOCH = int(200 * BATCH / Ntrain)\n",
" # Number of training epochs, the total iteration number \"EPOCH * (Ntrain / BATCH)\" is chosen to be about 200\n", " # Number of training epochs, the total iteration number \"EPOCH * (Ntrain / BATCH)\" is chosen to be about 200\n",
"LR = 0.01 # Set the learning rate\n", "LR = 0.01 # Set the learning rate\n",
"seed_paras = 19 # Set random seed to initialize various parameters\n", "seed_paras = 19 # Set random seed to initialize various parameters"
"seed_data = 2 # Fixed random seed required to generate the data set\n"
] ]
}, },
{ {
...@@ -167,7 +178,7 @@ ...@@ -167,7 +178,7 @@
" print(\"The dimensions of the training set x {} and y {}\".format(np.shape(train_x[0:Ntrain]), np.shape(train_y[0:Ntrain])))\n", " print(\"The dimensions of the training set x {} and y {}\".format(np.shape(train_x[0:Ntrain]), np.shape(train_y[0:Ntrain])))\n",
" print(\"The dimensions of the test set x {} and y {}\".format(np.shape(train_x[Ntrain:]), np.shape(train_y[Ntrain:])), \"\\n\")\n", " print(\"The dimensions of the test set x {} and y {}\".format(np.shape(train_x[Ntrain:]), np.shape(train_y[Ntrain:])), \"\\n\")\n",
"\n", "\n",
" return train_x[0:Ntrain], train_y[0:Ntrain], train_x[Ntrain:], train_y[Ntrain:]\n" " return train_x[0:Ntrain], train_y[0:Ntrain], train_x[Ntrain:], train_y[Ntrain:]"
] ]
}, },
{ {
...@@ -228,7 +239,7 @@ ...@@ -228,7 +239,7 @@
}, },
{ {
"data": { "data": {
"image/png": "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", "image/png": "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",
"text/plain": [ "text/plain": [
"<Figure size 432x288 with 1 Axes>" "<Figure size 432x288 with 1 Axes>"
] ]
...@@ -247,7 +258,7 @@ ...@@ -247,7 +258,7 @@
}, },
{ {
"data": { "data": {
"image/png": "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", "image/png": "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",
"text/plain": [ "text/plain": [
"<Figure size 432x288 with 1 Axes>" "<Figure size 432x288 with 1 Axes>"
] ]
...@@ -267,12 +278,6 @@ ...@@ -267,12 +278,6 @@
} }
], ],
"source": [ "source": [
"# Set parameters\n",
"Ntrain = 200 # Specify the training set size\n",
"Ntest = 100 # Specify the test set size\n",
"boundary_gap = 0.5 # Set the width of the decision boundary\n",
"seed_data = 2 # Fixed random seed\n",
"\n",
"# Generate data set\n", "# Generate data set\n",
"train_x, train_y, test_x, test_y = circle_data_point_generator(\n", "train_x, train_y, test_x, test_y = circle_data_point_generator(\n",
" Ntrain, Ntest, boundary_gap, seed_data)\n", " Ntrain, Ntest, boundary_gap, seed_data)\n",
...@@ -463,9 +468,9 @@ ...@@ -463,9 +468,9 @@
" state_tmp=np.dot(state_tmp, Rz(np.arccos(data[sam][1] ** 2)).T)\n", " state_tmp=np.dot(state_tmp, Rz(np.arccos(data[sam][1] ** 2)).T)\n",
" res_state=np.kron(res_state, state_tmp)\n", " res_state=np.kron(res_state, state_tmp)\n",
" res.append(res_state)\n", " res.append(res_state)\n",
"\n",
" res = np.array(res)\n", " res = np.array(res)\n",
" return res.astype(\"complex128\")\n" "\n",
" return res.astype(\"complex128\")"
] ]
}, },
{ {
...@@ -509,7 +514,7 @@ ...@@ -509,7 +514,7 @@
"<center> Figure 3: Parameterized Quantum Circuit </center>\n", "<center> Figure 3: Parameterized Quantum Circuit </center>\n",
"\n", "\n",
"\n", "\n",
"For convenience, we call the parameterized quantum neural network as $U(\\boldsymbol{\\theta})$. $U(\\boldsymbol{\\theta})$ is a key component of our classifier, and it needs a certain complex structure to fit our decision boundary. Similar to traditional neural networks, the structure of a quantum neural network is not unique. The structure shown above is just one case. You could design your own structure. Lets take the previously mentioned data point $x = (x_0, x_1)= (1,0)$ as an example. After encoding, we have obtained a quantum state $|\\psi_{\\rm in}\\rangle$,\n", "For convenience, we call the parameterized quantum neural network as $U(\\boldsymbol{\\theta})$. $U(\\boldsymbol{\\theta})$ is a key component of our classifier, and it needs a certain complex structure to fit our decision boundary. Similar to traditional neural networks, the structure of a quantum neural network is not unique. The structure shown above is just one case. You could design your own structure. Let's take the previously mentioned data point $x = (x_0, x_1)= (1,0)$ as an example. After encoding, we have obtained a quantum state $|\\psi_{\\rm in}\\rangle$,\n",
"\n", "\n",
"$$\n", "$$\n",
"|\\psi_{\\rm in}\\rangle =\n", "|\\psi_{\\rm in}\\rangle =\n",
...@@ -562,7 +567,7 @@ ...@@ -562,7 +567,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 8, "execution_count": 11,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-03-09T04:03:37.426687Z", "end_time": "2021-03-09T04:03:37.426687Z",
...@@ -572,7 +577,7 @@ ...@@ -572,7 +577,7 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"# Simulation of building a quantum neural network\n", "# Simulation of building a quantum neural network\n",
"def cir_Classifier(theta, n, depth): \n", "def cir_Classifier(theta, n, depth):\n",
" \"\"\"\n", " \"\"\"\n",
" :param theta: dim: [n, depth + 3], \"+3\" because we add an initial generalized rotation gate to each qubit\n", " :param theta: dim: [n, depth + 3], \"+3\" because we add an initial generalized rotation gate to each qubit\n",
" :param n: number of qubits\n", " :param n: number of qubits\n",
...@@ -599,7 +604,7 @@ ...@@ -599,7 +604,7 @@
" for i in range(n):\n", " for i in range(n):\n",
" cir.ry(theta[i][d], i)\n", " cir.ry(theta[i][d], i)\n",
"\n", "\n",
" return cir\n" " return cir"
] ]
}, },
{ {
...@@ -677,6 +682,7 @@ ...@@ -677,6 +682,7 @@
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Loss function\n", "### Loss function\n",
"\n",
"To calculate the loss function in Eq. (1), we need to measure all training data in each iteration. In real practice, we devide the training data into \"Ntrain/BATCH\" groups, where each group contains \"BATCH\" data pairs.\n", "To calculate the loss function in Eq. (1), we need to measure all training data in each iteration. In real practice, we devide the training data into \"Ntrain/BATCH\" groups, where each group contains \"BATCH\" data pairs.\n",
"\n", "\n",
"The loss function for the i-th group is \n", "The loss function for the i-th group is \n",
...@@ -690,7 +696,7 @@ ...@@ -690,7 +696,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 9, "execution_count": 6,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-03-09T04:03:37.439183Z", "end_time": "2021-03-09T04:03:37.439183Z",
...@@ -707,12 +713,13 @@ ...@@ -707,12 +713,13 @@
" :return: local observable: Z \\otimes I \\otimes ...\\otimes I\n", " :return: local observable: Z \\otimes I \\otimes ...\\otimes I\n",
" \"\"\"\n", " \"\"\"\n",
" Ob = pauli_str_to_matrix([[1.0,'z0']], n)\n", " Ob = pauli_str_to_matrix([[1.0,'z0']], n)\n",
"\n",
" return Ob" " return Ob"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 10, "execution_count": 7,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-03-09T04:03:37.503213Z", "end_time": "2021-03-09T04:03:37.503213Z",
...@@ -731,7 +738,6 @@ ...@@ -731,7 +738,6 @@
" super(Opt_Classifier, self).__init__()\n", " super(Opt_Classifier, self).__init__()\n",
" self.n = n\n", " self.n = n\n",
" self.depth = depth\n", " self.depth = depth\n",
" \n",
" # Initialize the parameters theta with a uniform distribution of [0, 2*pi]\n", " # Initialize the parameters theta with a uniform distribution of [0, 2*pi]\n",
" self.theta = self.create_parameter(\n", " self.theta = self.create_parameter(\n",
" shape=[n, depth + 3], # \"+3\" because we add an initial generalized rotation gate to each qubit\n", " shape=[n, depth + 3], # \"+3\" because we add an initial generalized rotation gate to each qubit\n",
...@@ -757,28 +763,27 @@ ...@@ -757,28 +763,27 @@
" \"\"\"\n", " \"\"\"\n",
" # Convert Numpy array to tensor\n", " # Convert Numpy array to tensor\n",
" Ob = paddle.to_tensor(Observable(self.n))\n", " Ob = paddle.to_tensor(Observable(self.n))\n",
" label_pp = paddle.to_tensor(label)\n", " label_pp = reshape(paddle.to_tensor(label), [-1, 1])\n",
"\n", "\n",
" # Build the quantum circuit\n", " # Build the quantum circuit\n",
" cir = cir_Classifier(self.theta, n=self.n, depth=self.depth)\n", " cir = cir_Classifier(self.theta, n=self.n, depth=self.depth)\n",
" Utheta = cir.U\n", " Utheta = cir.U\n",
" \n", "\n",
" # Because Utheta is achieved by learning, we compute with row vectors to speed up without affecting the training effect\n", " # Because Utheta is achieved by learning, we compute with row vectors to speed up without affecting the training effect\n",
" state_out = matmul(state_in, Utheta) # shape:[-1, 1, 2 ** n], the first parameter is BATCH in this tutorial\n", " state_out = matmul(state_in, Utheta) # shape:[-1, 1, 2 ** n], the first parameter is BATCH in this tutorial\n",
" \n", "\n",
" # Measure the expected value of Pauli Z operator <Z> -- shape [-1,1,1]\n", " # Measure the expectation value of Pauli Z operator <Z> -- shape [-1,1,1]\n",
" E_Z = matmul(matmul(state_out, Ob), transpose(paddle.conj(state_out), perm=[0, 2, 1]))\n", " E_Z = matmul(matmul(state_out, Ob), transpose(paddle.conj(state_out), perm=[0, 2, 1]))\n",
" \n", "\n",
" # Mapping <Z> to the estimated value of the label\n", " # Mapping <Z> to the estimated value of the label\n",
" state_predict = paddle.real(E_Z)[:, 0] * 0.5 + 0.5 + self.bias # |y^{i,k} - \\tilde{y}^{i,k}|^2\n", " state_predict = paddle.real(E_Z)[:, 0] * 0.5 + 0.5 + self.bias # |y^{i,k} - \\tilde{y}^{i,k}|^2\n",
" loss = paddle.mean((state_predict - label_pp) ** 2) # Get average for \"BATCH\" |y^{i,k} - \\tilde{y}^{i,k}|^2: L_i:shape:[1,1]\n", " loss = paddle.mean((state_predict - label_pp) ** 2) # Get average for \"BATCH\" |y^{i,k} - \\tilde{y}^{i,k}|^2: L_i:shape:[1,1]\n",
" \n", "\n",
" # Calculate the accuracy of cross-validation\n", " # Calculate the accuracy of cross-validation\n",
" is_correct = (paddle.abs(state_predict - label_pp) < 0.5).nonzero().shape[0]\n", " is_correct = (paddle.abs(state_predict - label_pp) < 0.5).nonzero().shape[0]\n",
" acc = is_correct / label.shape[0]\n", " acc = is_correct / label.shape[0]\n",
"\n", "\n",
" return loss, acc, state_predict.numpy(), cir\n", " return loss, acc, state_predict.numpy(), cir"
" "
] ]
}, },
{ {
...@@ -846,20 +851,21 @@ ...@@ -846,20 +851,21 @@
}, },
"outputs": [], "outputs": [],
"source": [ "source": [
"def QClassifier(Ntrain, Ntest, gap, N, DEPTH, EPOCH, LR, BATCH, seed_paras, seed_data,):\n", "def QClassifier(Ntrain, Ntest, gap, N, DEPTH, EPOCH, LR, BATCH, seed_paras, seed_data):\n",
" \"\"\"\n", " \"\"\"\n",
" Quantum Binary Classifier\n", " Quantum Binary Classifier\n",
" Input:\n", " Input:\n",
" Ntrain # Specify the training set size\n", " Ntrain # Specify the training set size\n",
" Ntest # Specify the test set size\n", " Ntest # Specify the test set size\n",
" gap # Set the width of the decision boundary\n", " gap # Set the width of the decision boundary\n",
" N # Number of qubits required\n", " N # Number of qubits required\n",
" DEPTH # Circuit depth\n", " DEPTH # Circuit depth\n",
" BATCH # Batch size during training\n", " BATCH # Batch size during training\n",
" EPOCH # Number of training epochs, the total iteration number \"EPOCH * (Ntrain / BATCH)\" is chosen to be about 200\n", " EPOCH # Number of training epochs, the total iteration number \"EPOCH * (Ntrain / BATCH)\" is chosen to be about 200\n",
" LR # Set the learning rate\n", " LR # Set the learning rate\n",
" seed_paras # Set random seed to initialize various parameters\n", " seed_paras # Set random seed to initialize various parameters\n",
" seed_data # Fixed random seed required to generate the data set\n", " seed_data # Fixed random seed required to generate the data set\n",
" plot_heat_map # Whether to plot heat map, default True\n",
" \"\"\"\n", " \"\"\"\n",
" # Generate data set\n", " # Generate data set\n",
" train_x, train_y, test_x, test_y = circle_data_point_generator(Ntrain=Ntrain, Ntest=Ntest, boundary_gap=gap, seed_data=seed_data)\n", " train_x, train_y, test_x, test_y = circle_data_point_generator(Ntrain=Ntrain, Ntest=Ntest, boundary_gap=gap, seed_data=seed_data)\n",
...@@ -916,7 +922,7 @@ ...@@ -916,7 +922,7 @@
" # Draw the decision boundary represented by heatmap\n", " # Draw the decision boundary represented by heatmap\n",
" heatmap_plot(myLayer, N=N)\n", " heatmap_plot(myLayer, N=N)\n",
"\n", "\n",
" return summary_test_acc\n" " return summary_test_acc"
] ]
}, },
{ {
...@@ -970,7 +976,7 @@ ...@@ -970,7 +976,7 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"The main program finished running in 7.169757127761841 seconds.\n" "The main program finished running in 8.05081820487976 seconds.\n"
] ]
} }
], ],
...@@ -996,6 +1002,7 @@ ...@@ -996,6 +1002,7 @@
" \n", " \n",
" time_span = time.time()-time_start\n", " time_span = time.time()-time_start\n",
" print('The main program finished running in ', time_span, 'seconds.')\n", " print('The main program finished running in ', time_span, 'seconds.')\n",
"\n",
"if __name__ == '__main__':\n", "if __name__ == '__main__':\n",
" main()" " main()"
] ]
...@@ -1007,6 +1014,387 @@ ...@@ -1007,6 +1014,387 @@
"By printing out the training results, you can see that the classification accuracy in the test set and the data set after continuous optimization has reached $100\\%$." "By printing out the training results, you can see that the classification accuracy in the test set and the data set after continuous optimization has reached $100\\%$."
] ]
}, },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Benchmarking Different Encoding Methods\n",
"\n",
"Encoding methods are fundemental in supervised quantum machine learning [4]. In paddle quantum, commonly used encoding methods such as amplitude encoding, angle encoding, IQP encoding, etc., are integrated. Simple classification data of users (without reducing dimensions) can be encoded by an instance of the ``SimpleDataset`` class and image data can be encoded by an instance of the ``VisionDataset`` class both using the method ``encode``."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'numpy.ndarray'>\n",
"(100, 4)\n"
]
}
],
"source": [
"# Use circle data above to accomplish classification\n",
"from paddle_quantum.dataset import *\n",
"\n",
"# The data are two-dimensional and are encoded by two qubits\n",
"quantum_train_x = SimpleDataset(2).encode(train_x, 'angle_encoding', 2)\n",
"quantum_test_x = SimpleDataset(2).encode(test_x, 'angle_encoding', 2)\n",
"\n",
"print(type(quantum_test_x)) # ndarray\n",
"print(quantum_test_x.shape) # (100, 4)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here we define an ordinary classifier, and it will be used by different data afterwards."
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"# A simpler classifier\n",
"def QClassifier2(quantum_train_x, train_y,quantum_test_x,test_y, N, DEPTH, EPOCH, LR, BATCH):\n",
" \"\"\"\n",
" Quantum Binary Classifier\n",
" Input:\n",
" quantum_train_x # training x\n",
" train_y # training y\n",
" quantum_test_x # testing x\n",
" test_y # testing y\n",
" N # Number of qubits required\n",
" DEPTH # Circuit depth\n",
" EPOCH # Number of training epochs\n",
" LR # Set the learning rate\n",
" BATCH # Batch size during training\n",
" \"\"\"\n",
" Ntrain = len(quantum_train_x)\n",
" \n",
" paddle.seed(1)\n",
"\n",
" net = Opt_Classifier(n=N, depth=DEPTH)\n",
"\n",
" # Test accuracy list\n",
" summary_iter, summary_test_acc = [], []\n",
"\n",
" # Adam can also be replaced by SGD or RMSprop\n",
" opt = paddle.optimizer.Adam(learning_rate=LR, parameters=net.parameters())\n",
"\n",
" # Optimize\n",
" for ep in range(EPOCH):\n",
" for itr in range(Ntrain // BATCH):\n",
" # Import data\n",
" input_state = quantum_train_x[itr * BATCH:(itr + 1) * BATCH] # paddle.tensor\n",
" input_state = reshape(input_state, [-1, 1, 2 ** N])\n",
" label = train_y[itr * BATCH:(itr + 1) * BATCH]\n",
" test_input_state = reshape(quantum_test_x, [-1, 1, 2 ** N])\n",
"\n",
" loss, train_acc, state_predict_useless, cir = net(state_in=input_state, label=label)\n",
"\n",
" if itr % 5 == 0:\n",
" # get accuracy on test dataset (test_acc)\n",
" loss_useless, test_acc, state_predict_useless, t_cir = net(state_in=test_input_state, label=test_y)\n",
" print(\"epoch:\", ep, \"iter:\", itr,\n",
" \"loss: %.4f\" % loss.numpy(),\n",
" \"train acc: %.4f\" % train_acc,\n",
" \"test acc: %.4f\" % test_acc)\n",
" summary_test_acc.append(test_acc)\n",
"\n",
" loss.backward()\n",
" opt.minimize(loss)\n",
" opt.clear_grad()\n",
"\n",
" return summary_test_acc"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we can test different encoding methods on the circle data generated above. Here we choose five encoding methods: amplitude encoding, angle encoding, pauli rotation encoding, IQP encoding, and complex entangled encoding. Then the curves of the testing accuracy are shown below."
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Encoding method: amplitude_encoding\n",
"epoch: 0 iter: 0 loss: 0.3066 train acc: 0.4000 test acc: 0.5400\n",
"epoch: 0 iter: 5 loss: 0.2378 train acc: 0.7000 test acc: 0.7000\n",
"epoch: 0 iter: 10 loss: 0.2308 train acc: 0.8000 test acc: 0.6700\n",
"epoch: 0 iter: 15 loss: 0.2230 train acc: 0.8000 test acc: 0.6100\n",
"Encoding method: angle_encoding\n",
"epoch: 0 iter: 0 loss: 0.2949 train acc: 0.5000 test acc: 0.3600\n",
"epoch: 0 iter: 5 loss: 0.1770 train acc: 0.7000 test acc: 0.7000\n",
"epoch: 0 iter: 10 loss: 0.1654 train acc: 0.8000 test acc: 0.7000\n",
"epoch: 0 iter: 15 loss: 0.1966 train acc: 0.7000 test acc: 0.5800\n",
"Encoding method: pauli_rotation_encoding\n",
"epoch: 0 iter: 0 loss: 0.2433 train acc: 0.6000 test acc: 0.7000\n",
"epoch: 0 iter: 5 loss: 0.2142 train acc: 0.7000 test acc: 0.7000\n",
"epoch: 0 iter: 10 loss: 0.2148 train acc: 0.7000 test acc: 0.7000\n",
"epoch: 0 iter: 15 loss: 0.2019 train acc: 0.8000 test acc: 0.7600\n",
"Encoding method: IQP_encoding\n",
"epoch: 0 iter: 0 loss: 0.2760 train acc: 0.6000 test acc: 0.4200\n",
"epoch: 0 iter: 5 loss: 0.1916 train acc: 0.6000 test acc: 0.6200\n",
"epoch: 0 iter: 10 loss: 0.1355 train acc: 0.9000 test acc: 0.7300\n",
"epoch: 0 iter: 15 loss: 0.1289 train acc: 0.9000 test acc: 0.6700\n",
"Encoding method: complex_entangled_encoding\n",
"epoch: 0 iter: 0 loss: 0.3274 train acc: 0.3000 test acc: 0.2900\n",
"epoch: 0 iter: 5 loss: 0.2120 train acc: 0.7000 test acc: 0.7000\n",
"epoch: 0 iter: 10 loss: 0.2237 train acc: 0.7000 test acc: 0.7000\n",
"epoch: 0 iter: 15 loss: 0.2095 train acc: 0.8000 test acc: 0.7200\n"
]
}
],
"source": [
"# Testing different encoding methods\n",
"encoding_list = ['amplitude_encoding', 'angle_encoding', 'pauli_rotation_encoding', 'IQP_encoding', 'complex_entangled_encoding']\n",
"num_qubit = 2 # If qubit number is 1, CNOT gate in cir_classifier can not be used\n",
"dimension = 2\n",
"acc_list = []\n",
"\n",
"for i in range(len(encoding_list)):\n",
" encoding = encoding_list[i]\n",
" print(\"Encoding method:\", encoding)\n",
" # Use SimpleDataset to encode the data\n",
" quantum_train_x= SimpleDataset(dimension).encode(train_x, encoding, num_qubit)\n",
" quantum_test_x= SimpleDataset(dimension).encode(test_x, encoding, num_qubit)\n",
" quantum_train_x = paddle.to_tensor(quantum_train_x)\n",
" quantum_test_x = paddle.to_tensor(quantum_test_x)\n",
" \n",
" acc = QClassifier2(\n",
" quantum_train_x, # Training x\n",
" train_y, # Training y\n",
" quantum_test_x, # Testing x\n",
" test_y, # Testing y\n",
" N = num_qubit, # Number of qubits required\n",
" DEPTH = 1, # Circuit depth\n",
" EPOCH = 1, # Number of training epochs\n",
" LR = 0.1, # Set the learning rate\n",
" BATCH = 10, # Batch size during training\n",
" )\n",
" acc_list.append(acc)"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYIAAAEWCAYAAABrDZDcAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAAsTAAALEwEAmpwYAABqp0lEQVR4nO2dd1hUR9uH76FXRYq9gF0QsIC9RRM1MdZoTDTWVGPUN74x9Uui6f1NNKZb0kzsxpgYjTHGLmDvDVFBRXovy+58f5xlsyAgIMuCzH1dXHDOmTPnOWeX+Z15ZuZ5hJQShUKhUNRcbKxtgEKhUCisixIChUKhqOEoIVAoFIoajhIChUKhqOEoIVAoFIoajhIChUKhqOEoIajmCCF8hRBSCGFnpev3E0JEF3OstxDidCXZMVcI8YPx76ZCiHQhhK1xu54QYrsQIk0I8aHQWCKESBJChFWGfdWNkp5ndUIIsU0I8UgF1bVUCPFGRdRV1bBK43G7IoSIAuoBekAH7AaekFJetqZd1kJKuQNoY4XrXgLczHY9BsQDtaSUUgjRG7gLaCylzKhM24QQvsAFwF5KmVeZ1y4vRTzPKokQYi7QUkr5kLVtqW6oHkHFM1RK6QY0AGKBBVa2x2JYqxdSDpoBJ+S/qyebAVHlEYFqdM8KRalRQmAhpJTZwCrAP3+fEMJRCPGBEOKSECJWCPGFEMLZeKyfECJaCPFfIcR1IcRVIcQUs3OdjW6Ni0KIFCHEzvxzjYw31hsvhHjJ7Ly5QoiVQogfjK6Ro0KI1kKIF4zXuSyEGGhWfooQ4qSxbKQQ4nGzY/k2PieEuAYsKXzfQoiZQogTQojGhd1GQogoIcQzQogjxntYLoRwMjv+rPG+rwghHjG6vFoW9XyFEH5CiH+Mdv4JeJsdM7nLhBBLgUnAs0b3xuPAN0B34/Y84zn3CiEOCSGShRC7hRBBhex+TghxBMgw1tvNWC5ZCHFYCNHPrPw2IcTrQohdRvs2CyHy7dtu/J1svH73Iu7NRgjxvBDivBAiQQixQgjhWejeJhXzedsKIV40npsmhNgvhGhiPNZDCBFufPbhQogeZX2epbg/hBATjd/TBCHEy8bnd2cxn+NSIcRnQoiNxuexSwhRXwjxsdBcd6eEEB3NyjcUQqwWQsQJIS4IIWYa9w8GXgTGGus5bHaZZiXYOkwIcdz4OW4TQrQzO9ZRCHHAeN5ywPy76i2E2GA8L1EIsUMIUX3bUyml+qmgHyAKuNP4twvwLfCd2fH/AesBT8Ad+BV423isH5AHvAbYA/cAmUAd4/GFwDagEWAL9AAcAV9AAl8DzkAwkAO0M543F8gGBqG5Ar9Dc028ZLzOo8AFMxuHAC0AAfQ12tCpkI3vGq/tbNwXbTz+CnAA8DErH13o+YQBDY3P4CSa6wxgMHANCDA+ux+M99WymGe9B/jIaEcfIA34wXgs/5nYGbeXAm+YnTsZ2Gm23RG4DnQ1PttJRlsdzew+BDQx3nMjIMH4GdmguZkSzO57G3AeaG0svw14pyjbirm3WcBeoLHx/r4Efip0fnGf9xzgKJpLThiPexmfdxIwAe178KBx26scz7Ok+/MH0oFegAPwAZqb9M5i7nUpmtuuM1pDuxXt+znR+Fm8AfxtLGsD7Ef7njkAzYFIYJDZd/2HQvWXZGtrIMP4+dkDzwLnjHU7ABeBp43HRhvv4w3juW8DXxiP2QO9AWHtNqjcbZe1DbidftAajHQg2filuQIEGo8J45euhVn57hgbYbRGMwuzBgKtcepm/AfIAoKLuGb+P2ljs31hwAPGv+cCf5odG2q00da47W4836OYe1oHzDKzMRdwMjveD4hBa0R2ArULHSssBA+Zbb8HfGH8ezFGUTRut6QYIQCaogmSq9m+ZZRfCD4HXi90jdNAXzO7p5odew74vlD5TcAk49/bgP8zO/Yk8EdRthXzzE8CA8y2Gxi/T3al+LxPA8OLqHMCEFZo3x7jsyjr8yzp/l7BKFrGbRfjd6YkIfjabHsGcNJsOxBINv7dFbhU6PwXgCVm3/WihKA4W18GVpgds0H7LvdDE8MrmDXuaGN++ULwGvALxbyoVLcf5e+seEZIKbcIbYbFcOAfIYQ/YED7p9gvhMgvK9DeevJJkAUHEDPRBum80d6Wzpdw3WtFnJdPrNnfWUC8lFJvto2xfLIQ4m7gVbS3JRujzUfNzo+TmtvLHA+0AdmxUsqUEmwsys6Gxr8bAhFmx0oaYG8IJMmCPv6LaG/s5aEZMEkIMcNsn4OZbYXtaQaMEUIMNdtnD/xttl3S51Eae9YKIQxm+/RoExFuVn8Tiv6eNER7RuZcROvdlOd5Fnf9hpg9KyllphAioYR64MbvZ+Ht/LqbAQ2FEMlmx22BHTepvyRbTc9ESmkQQlxGeyZ6IEYaW30j5s/vfTTh2Wz8f/5KSvnOTeyoslRfn1YVR0qpl1KuQftC9ULr/mYBAVJKD+NPbakNLN+MeDT3TgvLWayNYQCr0brz9aSUHsDvaIKVT1HhapOAe4ElQoie5bz8VTRXSD4lNUJXgTpCCFezfU3LeV3QGq43zT4XDymli5TyJ7MyslD57wuVdy1lQ1DU8yvKnrsL1e8kpYwp5blFfU+uoDWk5jRFewOuyOdZ4HMU2jiWVznrKsxltB60+XNxl1LeYzxemmdrToFnIrQWvQn/PpNGwuytDbNnIqVMk1L+V0rZHBgGzBZCDCjHPVUJlBBYCKExHKiD1tU1oPl1/yeEqGss00gIMehmdRnPXQx8ZBwssxVCdDc23BWJA5qPOA7IM/YOBpZ8isnGbcB4YI0Qoks5rr0CmCKEaCeEcEHrthd3rYtovYd5QggHIUQvNJdXefkaeEII0dX4ubkKIYYIIdyLKf8DMFQIMcj4WTgJbWC8cTHlzYlD6x02L6HMF8CbQohmAEIIH+N3qTR8A7wuhGhlvJcgIYQXmqC3FkKME9pg91g0f/6GCn6eq9CeTQ8hhAPaW7Mo+ZRSEwakCW3g3tn47NsLIUKNx2MB3zIM2q4AhgghBggh7IH/oo237EZzm+UBM4UQ9kKIUYDpey20yQUtjUKRgvbCZ7jhCtUEJQQVz69CiHQgFXgTzW983HjsObTBqL1CiFRgC6WfZ/8MmosmHEhEG7Ct0M9PSpkGzET7B0kCxqENbpf2/D+BqWjPoFMZr70RmI/mXjmHNlgK2j9mUYxD8xknormyvivL9QpdOwJt0PxTtPs+h+Y7L678ZTS334toDftltEHam34eUspMtO/FLuOMk25FFPsE7blvFkKkoT2LrqW8nY/QPr/NaN/BRYCzlDIBrdf2X7SB7WeBe6WU8cbzKuR5Gr/rM4Cf0d6q09HGuor7HMtStx7tHjqgDSjHowlfbWORlcbfCUKIA6Wo7zTwENoU73g08RsqpcyVUuYCo9C+B4nAWGCN2emt0P5/09FE4zMppblrsFohCrrAFIqqgXEa3zG0mTvVYuGV4kaEEG5okydaSSkvWNkcRTGoHoGiyiCEGCm0tRZ10Ho8vyoRqH4IIYYKIVyMYw4foPVko6xrlaIklBAoqhKPo7kRzqP5XKdZ1xxFORmONhB7Bc2F8oBUrocqjXINKRQKRQ1H9QgUCoWihlPtFpR5e3tLX19fa5uhUCgU1Yr9+/fHSyl9ijpW7YTA19eXiIiImxdUKBQKhQkhROGV5SaUa0ihUChqOEoIFAqFooajhEChUChqOEoIFAqFooajhEChUChqOEoIFAqFooajhEChUChqOEoIFAqFogqTo88h4loEnx/+nFOJpyxyjWq3oEyhUChuZ3L0ORyJO0LEtQjCY8M5fP0wuYZcBAJPR0/aerat8GsqIVAoFAorkp2XzZG4I4THhhNxLYIjcUfINeRiI2xo69mWB9o+QGj9UDrW7Uhtx9o3r7AcKCFQKBSKSiQrL0tr+K+FE34tnKPxR9EZdNgIG9p5tmNcu3GE1AuhY72O1HKoVSk2KSFQKBQKC5KVl8Wh64eIiI3Q3vjjj5BnyMNG2ODv6c9D7R4ipH4IHet2xN2huDTZlkUJgUKhUFQgmbpMDsUdIuJaBBGxERyNP0qeIQ9bYYu/lz8T/CcQWk9z9bg5uFnbXEAJgUKhUNwSmbpMDl0/RHis5uo5Hn+cPKk1/AHeAUz0n2jy8bvau1rb3CJRQqBQKBRlIEOXwcHrB02zek7EnyBP5mEn7AjwDmBy+8mE1AuhQ90OVbbhL4wSAoVCoSiB9Nx0Dl4/SHhsOPuv7ed4wnH0Uo+dsKO9d3umtJ9CSP0QOvh0wMXexdrmlgslBAqFQmFGem46B64f0N74r4VzMvGk1vDb2BHkHcTU9lMJrR9KsE9wtW34C6OEQKFQ1GjSctM4EHuAiNh/G36DNJga/ocDHzY1/M52ztY21yIoIVAoFDWK1NxUDsQeIPxaOBGxEZxKPIVBGrC3sSfIJ4jHgh4jpF4IQT5Bt23DXxglBAqF4rYmJSdFa/iNK3dPJZ5CInGwcSDIJ4jHgx4ntH4ogd6BONk5Wdtcq6CEQKFQmMg+cYKExUvIOXsW544dcAkNxSU0FPu6da1tWqlJyUkxLd6KiI3gdOJpU8PfoW4HpgVPI6S+9sbvaOtobXOrBEoIFIoajpSSjJ27SFi8iMw9e7FxdcUpKJDUXzeQ/PNyABz8/DRR6NJFE4Z6VUcYkrOT2R+73/TGfybpDBKJo60jHXw68GSHJwmpF0KgT6Bq+ItBCYFCUUORubmk/P47iYuXkHPmDHZ161L3mf/iMXYstu7uyLw8sk+eJDMsnMywMFJ//53kFSsAcGjWTBOFLl1w6RKKfb16lWZ3UnaS1vBfCyc8NpyzSWcBcLJ1IrhuMNM7TCe0fijtvdvjYOtQaXZVZ4SU0to2lImQkBAZERFhbTMUimqLPi2N5BUrSfzuO/JiY3Fs1QrPqVOpPeQehEPxDafU68k+eYrMsDDtZ/9+DGlpANg3a4prvjCEhmJfv36F2ZuYnWhy84RfC+dc8jkAnO2c6eDTgZD6IVrD79Uee1v7Crvu7YYQYr+UMqTIY0oIFIqage7aNRK/+57kFSswpKfj0q0bXlOn4Nq7N0KIMtcn9XqyT53Segzh4WRGRGBITQXAvmlTXEJDTOJg36BBqetNyEowNfr7Y/cXaPg71u1ISD2t4Q/wCritGn693kB2uo6sNB1Z6blkG39npenISsslK11HQO+GNPX3Klf9JQmBcg0pFLc52adPk7h4MSm//Q5SUmvQIDynTsW5fcAt1StsbXEOCMA5IACvKZORej05p0+TGR5ORlg4aVv+ImX1GgDsGzc2uZFcQ0Oxb9TIVE98VrxpcDf8WjiRKZGA1vB3qtuJIc2HEFIvhADvAOxtqk/Dr88zNuzmjXl+456u0xp6YwOflZZLTmZe0RUJcHK1x9ndofgyt4jqESgUtyFSSjL37iVh0WIydu5EuLjgMfo+PCdOwqFxo5tXUBE2GAzknDlDZlgYGWFhZIVHoE9JAUBXz5OYVh7sa5DBdu944jwELnYudKzXkdB6oYTWD6WdV7sq1fDr8wz/NuTGRj07Pb+Bz2/QjW/z6bpiG20hwMlNa9idzX47mW+72+Pspv12dLXHxqbsPbYbr6t6BApFjUDqdKT+sYmEJYvJOXESW29vfP7zH+o8MBZbD49KtUXY2ODUti2pTT052sub8KveRB/eTZ0TMfhfTsJ/fxJjsyRjAVnfh1rduuPm1BWXtl2w925ULndVWcjT6Qs25umF3trTdGSn55KZpiM7LZfcbH0x9ym0ht3YiPs0dTc14v829vY4Gfc5udgjKqBhr0iUECgUtwH69AxSVq8i4dtvybtyFYfmzWnwxuvUGjoUG8fKnTIZmxFr8vFHxEZwMfUiAG72bnRq0wn/PuMIqR9CG4/W6M9HaeMLYWFk/rODtHXrAbBr2ADX/OmqXbpg37jxTYUhL1f/b2Nu1qhn57tmCr2964pp2G1sBE5mb+T1mjnh5O6Ai1ljbt7QOzrbVbmGvawo15BCUY3RXb9O0vc/kLR8OYbUVFxCQvCcOhW3fn0RNjaVYsO1jGumgd3wa+FcSrsEgLu9O53qdSK0figh9UNoW6cttja2xdYjDQZyz58nIyyMzLBw0iIOaQ22gxv6uk0RrQKQTVqi92pIrnAyuWLy39rzcopp2G1Fia4XcxeNk5s9ji52Fu+NWAOruYaEEIOBTwBb4Bsp5TuFjv8PuMO46QLUlVJ6WNImheJ2IOfcORKWLCF1/a9IvR73u+7Ca+oUnIODLX7t/IY//43/ctplANwd3OlctzP3t7mf0PqhtKnTpkDDr8vRk5GWVcD1kv92nl3gLd6PLNmIvMBhBS+cDZwFcToOB30WTo4SZw9n6jbwxCXIG5daDji7ORT0v9dywMHJ9rZs2CsSiwmBEMIWWAjcBUQD4UKI9VLKE/llpJRPm5WfAXS0lD0KRXVHSklmeDiJixaT/s8/CCcnPMaMwXPyJByaNrXYda+kXzG5esKvhROTHgMS6th6EVq7G2MaT6SlUxs8pQ85GXqyTuZyJVzH+bSjBaZC5ukMRdZva29TYNC0Tn1Xo2vmxrd12/gYdIf3kxUeRkZYOPr4eADs6tb9d+Vzl1AcfH1V418GLOYaEkJ0B+ZKKQcZt18AkFK+XUz53cCrUso/S6q3vK6hmPQYLqZcLPN5CssSfeIi+rh0XB1scbCtHFdGtcNgwO7MVezDz2F7NRnp7Iiusx+6jr5IZ8v4/5OkDZGpaVyNv05uhgFnnRtueg888cFZ54bItsNQzExGO3sbMx97vhumoEvG3Adv71i+N3YpJbkXokwL3DLCw9DHacJg6+ONa2gX0xiDg58SBqssKBNCjAYGSykfMW5PALpKKZ8qomwzYC/QWEp5g6NPCPEY8BhA06ZNO1+8WPYGfcmxJXy0/6Myn6ewHB6Z9Rhz5FlspZqzUKWxM+Dkbk+tWi4F39DN/exm/nZ7x+LHASyJlJLcqKh/F7iFhZF3/ToAtt7euHb5N1aSQ/PmNU4YqsP00QeAVUWJAICU8ivgK9B6BOW5wD1+99CxrvI8VQUOXk5iydYTTI6W5IpcnLpfJi1PT1p2HmnZOtKy9aRm68gzFHQlONja4uZoh7uTHbWc7HFzssXd0R53Z22fo50Ngtvgnzs9C5u9p7DddwqRlYOhSV0MvQMwtG0KlTQ7xTX1Ii1PL8cl9yL2LXtDv+ehSWilXLu8CCFw9PPD0c+POmPvR0qJ7uJFMsLDzeIlbQTA1ssLly5aZFXXLl1waNGixgmDOZYUghigidl2Y+O+ongAmG5BW6jnWo96rpUXGEtxI6nZOt7ccJLlEZm8b3uB6zn30PtOO4JG33tDWSklyZk6opOyiE7KJCY5y/T3uaQsomOzSM8p6Jtwc7SjkYczjevk/7iYfjeq40wdF/sq/c+eE3mBxKVLSVm3DqnT4TagP15TH8alk5VeYHKmQcQi2DUfFt0FLfpD3+ehaVfr2FNGhBA4+Pri4OtLnTFjNGG4fNm0wC0zLJy0jX8AYOvpaRxjMApDy5ZV+rtS0VjSNWQHnAEGoAlAODBOSnm8ULm2wB+AnyyFMWr6aPXk71PXeWHNUa6nZfN+u8tk7KuNvasbY98egk05xgaklKRm5XE5KdMkENpvo3AkZZFWSChcHGwLCYQzjTz+/dvT1cEq//yZBw6QsGgx6Vu3IuztqT1yJJ6TJuHY3K/SbSmS3AwIXwS750NGHDTvpwlCs+7WtuyWkFKii442jjGEkxEWRt7VqwDY1qlTYPDZsWXLSpuOaymsFnROCHEP8DHa9NHFUso3hRCvARFSyvXGMnMBJynl86WpUwlB9SIlS8frG06wan80req68fE99chcupCw5JGMmNmeRv6Wi2ufkqUrUiDy/07NLigUzva2/wpEoR5F4zrOeFWgUEi9nrS//iJx8RKyDh3CtnZt6owfR53x47HzKl9QMYuTmwkRi2HXx5og+PXVXEbNeljbsgpBSokuJsbkRsoMC0N35QoAth4epiQ9Ll274NiqVbUTBhV9VGEVtp6K5YU1R4lPz+WJvs2Z2b8FOUsms+zgBPwCPBj0VDer2peSpTMKQ0HXU75wpGTpCpR3srcxup5cbuhZNK7jgrfbzYXCkJ1Nyrp1JC5ZSu7Fi9g3bozn5Ml4jBqJjYuLJW+34sjNhP1LYOfHkHEd/PpoPQTfnta2rMLJjY75d+VzWBi6GM27bVu7Ns5m0VUdW7eu8sKghEBRqaRk6pi34ThrDsTQpp47H4wJJrBxbdj9KX8sT+ZiXjfGvd4Ld8+qnR82LVunCURiIddTsvZ3cmZBoXC0synUkzCOT3g400hkY/PLapKXLUOflIRTYCBeD0/F/a67ELbWmWVzy+Rmwv6lWg8hPRZ8e0Pf58Cvt7Utsxi6mJh/B5/Dw9Fd1hbT2dSujUtIiGlmkmObNlVOGJQQKCqNP0/E8tLaoyRk5DK9Xwum92+Jo50tXD3C5U9nsT7hZboO9SNkSBXxf98C6Tl5ph6FeW8iv3eRmJFLg4x4Rp7bzl2XwnHS6zjaJJBDPe9FBnagsWdBwfBxc6yQKJOVji4L9n8LO/8H6degWS/NZXQbC0I+uitXtLDbRnHQXdLCa9jUqoVLSIhpZpJT27ZWF3wlBAqLk5SRy7xfj7Pu0BXa1td6Ae0b1dYO6rLQf3EHK84+RZ6bLw/O646dfTV9Cy4lWYcPE/v1IrL+2oK0tSO++x0c6T6Ek47eJsFIyMgtcI6DrdajKG7mU133Ki4Uuiw48J0mCGlXoVlPYw+hjxZ7uQagu3bN5ErKCAtDd9EoDO7umjAYB6Cd2lW+MCghUFiUTcev8dLaYyRn5jL9jpZMv6MlDnZm3eLf53D47yvsTHuYu58IpHkHH+sZa0GkwUD6tm0kLF5MVsR+bGrVos4DD1DnofHY171xUDwz19ijKGJ8IiYpk/j0gkJhbytomC8S+bOdPP+d+VSvlhO2VUEodNlmgnAFmnY39hD61hhByEcXG/vv4HN4OLlRUQDYuLnh0rmzaeWzU7u2CDvLLutSQqCwCIkZucxdf5z1h6/g36AW748JIqBh7YKFzmwm8/tH+DHpa+q3rse9M4Jvu/nZhpwcUtav1waAIyOxa9gAr0mTqH3faGzdXMtdb1au3uhmKjTzySgccWk5Bcrb2ZgJhdn4hCYYLtSvbKHQZcPB72HHR5ogNOmmCULzfjVOEPLRxV7XegzGXkPuhQsA2Li64hzSWRt8Dg3Fyd+/woVBCYGiwtl49Cov/3KMlCwdM/q3Ylq/FtgXXg+QHgefd2dr4mOcTgnlgVe6UKd++RvGqoY+OZmkn38m8Ycf0cfH4+jfDq+pD1Nr8CCLv90BZOv0N8x2Mh+zuF6EUDTwcKKxh4txULvgwHb9Wk7YWSLeU17Ov4KQGgNNumouoxb9a6wg5KO7fp2siAjTArfcSC1Np42rK86dO5lWPjv5+yPsby1bmxICRYWRkJ7DK+uP89uRq7RvVIv3RwfTrkGtGwtKCcvGEnvqEqvi36LDnU3peV/LyjfYAuRGx5D47bckr16NzMzEtXdvvKZOwaVbtyrV28nW6bliFIqiehaxqQWFwtZGUL+WE43rONPcx42ufp50be5Jg9rOFWNQXg4c/MEoCNHQOFTrIbQYUOMFIZ+8uDgy84UhPJzcc+cBsHFxwblTJzwnT8atV/mm6SohUFQIvx3RegFp2TpmDWjF432L6AXkE/Y18rc5rDb8SFpObcbP64aDc1UJbVU+so4dJ3HxIlL/2AQ2NtQeMgTPqVNxatPa2qaVi5w8PVeTswuNT2i/T8emkWZccNfMy4Vufl50be5Jt+ZeNPS4RWHIy4FDP2qCkHIZGoVAvxegpRKEwuTFx5MZEWGcrhqG91MzqDVoYLnqUkKguCXi0nJ45ZdjbDx2jcBGtflgTDBt6rsXf8L1U/BVX046P8LWswMYMLkdbbs1qDyDKxApJRk7dpCwaDGZ+/Zh4+aGx9j78ZwwAfv69a1tnsXQGyQnr6ayNzKBfRcS2ReZYFqJ3dTTha5+mih0a+FFo/IKQ14uHF4G2z+ElEvQqLO2MK3VXUoQikFKWe5epxICRbmQUvLrkau8+ssxMnL0/OeuVjzWu3nJfuS8HPhmADnJSfwY/xm167oy6pnO1S6nq8zNJWXDbyQuWUzO2XPY1auH58SJeNw/Blv3EkTwNkVvkJy6lsq+yESTOOSvvG5cx1kTheZedPXzpIlnGVdI5+XC4Z9gxweQfAkadtJcRq0GKkGoQJQQKMrM9bRsXl53jE3HYwlu4sEHo4NoVa8UDeDm/4PdC9jZcCWHD9ox5vkQ6jYrYgyhiqJPTSVp+XKSvv+BvOvXcWzdGq+Hp1Lr7rsRDg7WNq/KYDBITsemsTcygb2RCYRdSCTJuNK6kUe+MGi9hsZ1nEv3FqvXaYKw/QNIvggNO2o9hNaDlCBUAEoIFKVGSskvh64w99fjZObqmX1Xax7p5Ve62SSR2+C74SS2mcnyHf1p26MBdzzU1uI2VwS6q1dJ/PY7kleuxJCRgWuP7nhOmYprr55VagC4qmIwSM5cT2PveaMr6UIiicYFc408nLXxBT+t19DE8ybCoNfBkeWw/X1IioIGHbRZRm3uVoJwCyghUJSK66nZvLj2GFtOxtKxqQfvjw6mZV230p2cmQif90Tau7Je/yVxlzMYP68bzu5V+y06+9QpEhYv1hKWSEmtu+/Ga+oUnPz9rW1atcZgkJy9ns6+CwnGXsO/wtCgtlOBHkNTT5eihUGvgyMrjIJwAeoHaS6jNvcoQSgHSggUJSKlZO3BGOauP05OnoFnBrZhai+/0i8+khJWTITTG4ns9TsbV6TTe2xrgu5obFnDy4mUkozdu0lctJiM3buxcXHRksBPmoh9w4bWNu+2RErJuevpJlHYG5lgCrFRv5aTSRS6NvfC16uQMOjz4KhREBIjoX6g5jJqO0QJQhlQQqAoltjUbF5cc5S/Tl2nc7M6vDc6iBY+pewF5HPwB/hlOnn9XmPZn6E4ONly/4uh5Uo4Y0mkTkfqxo0kLF5CzqlT2Pp44zlhInXG3o9t7do3r0BRYUgpOR+Xzp5IbUbS3shE4tO1dQ31ajkaB561XoOft6smDPo8OLrSKAjnoV4g9H0W2t4LVSzSZ1VECYHiBqSUrD4Qw2u/HidXb2DOoLZM7uFb9hAECefhi97QqBPh3vMJ2xDFiKc70qhNHcsYXg706ekkr1hJ4nffkXftGg4tW+A1ZSq1ht6LjRoArhJowpBhdCVpPYb8EBp13R3pauZKau7piDi2Bra/BwnnoF57oyAMVYJQAkoIFAW4mpLFC2uOsu10HKG+dXhvdDB+3uUI/aDXweJBkHCO1Af+YdmHF/EL8mbQo+0r3uhyoIuNJen770lavgJDWhouoaF4PjwVtz59qlyseEVBpJRciM8wicLeyARTyAwfd0e6+nnS3c+DAfqd1Ds4H5FwFuoGaILQbpgShCJQQqAAtH+ulRHRvL7hBHkGybOD2zCpu2/5QxtvfVN7KxuzlD92tuTi8QTGze1m9YQz2WfOkLh4CSm//QZ6Pe6DBuI1dSrOgYFWtUtRfqSURCVkamsYjK6ka6nZANR1tWOaz2FGpS2jdsYFZF1/RJ854D9CCYIZSggUXEnO4vk1R9l+Jo6ufp68NzqIZl63EADu4h5Yeg8EPcDldm+y/uNDdB3WnJB7fCvM5rIgpSRzXxgJixeRsX0HwtkZj/vuw3PSRByaNLGKTQrLIaXkYkJmAVdSbEomQ2z28rTDOpoTTZJbC7K6/5cG3cYibKt3eJOKQAlBDUZKyc/hl3nzt5MYpOT5u9vyUNdmt5bgJDsFvugFwgb9I/+w/IPT6HV6Hny1a6UnnJF5eaRu2kTi4iVkHz+OrZcXng+Nx+OBB7CrU3XGKRSWRUrJ5cQsrcdw/jou5zYwIXc5rW1iiKQxf9ebjH3QKLq2qEurum5VO8GPhVBCUEOJTsrkhTVH2XE2nu7NvXj3viCaelVAgvQ1j8HRVTD1Dw6facDOlWe5Z1ogfsGVl3DGkJFB8uo1JH77LbqYGBx8ffGcOoXaw4dj4+hYaXYoqiZSSqITM7i86yf8ji+kQc4FzhkaMj9vJLscexPavC7dmnvStbkXbeq51whhUEJQw5BSsizsEm/9dhKAF+5px7guTSvmy350Fax+GPq9QGan2fz46l7q+9WqtIQzeXFxJP7wI0k//4whJQXnTp3wengqbnfcoQaAFUVjMMDJ9eRufRuHhFNcd2jK53IU36aFYMAGDxd7LeS2ceVz2/q3pzAoIahBXE7M5LnVR9h9PoGeLb14Z1RQ2YOAFUfyJfi8F/i0gSkb2frjWU7vu8YDL1s+4UxOZKS2AviX9ci8PNzvvBPPqVNw6djRotdV3EYYDHDqV9j2Llw/js6jBQf9HmV1Thd2R6VwOTELgNrO9nTJj67a3JN29WvdFsJQkhCoEZTbBINB8uO+i7y98RQ2QvDWyEAe7NKk4t7SDXpY8zhIA4z6ithLmZzcfZWOdzW1mAhIKcnav5+ERYtJ//tvhKMjtUffh9ekSTj4+lrkmorbGBsb8B+urTc4tQH7f96ly8Hn6eLZAgbOIabpveyLSjFFV/3zRCygCUOor6dpHUO7BrWqRm7oCkQJwW3ApYRMnl19mL2RifRu5c079wWVP0Z8cez8H1zaDSO+QHr4sv2r/bjUcrDILCGp15P25xYSliwm+/ARbD088J4+nTrjx2Hn6Vnh11PUMGxswH+YtiL59G/wz7uw7gkaeTZnVJ85jBp5P9jacSU5i30XEkyht7ec1ITB3cmugCvJv2H1FwblGqrGGAyS7/ZE8e4fp7GzEfzfve24P6QCewH5xOyHRQO1hTqjF3Nyz1W2fneKOye3o00FJpwxZGWRvHYtiUu/RXfpEvZNm+I1ZTK1R4zAxrmChU2hyEdKOP07bHsHrh2BOn7QZw4EjQWzaafXUrILBNG7EJ8BgLujHaF+//YY/BvUskzu51tEjRHchkTFZ/Ds6iOEXUikb2sf3h4VeOspBIsiJx2+7KMlnJm2kxzc+fGVPdT2cWbUnM4VIjp5iYkk/fAjScuWoU9Oxik4CK+pD+N+5wCEbeVOR1XUYKSE0xvhn3fg6mGo4wu9n4HgB8D2xsTxsanZJlHYdyGByLh/hSHEt44pWU9Aw6ohDEoIbiMMBsnS3VG8t+kU9rY2vHyvP2M6N7bcjJ31M+DA9zDpV/Drzc6VZzm89TL3vxCKT9Nby9RlyM7m+ocfkbxiBTInB7f+/fF6eCrOnTqpHAAK6yElnPlD6yFcPQQezaDPMxD8YJGCkM/11Gz2XsgPopfAeaMwuJkJQ1c/TwIb1baKMCghuE2IjEvn2VVHiLiYxB1tfHhrVCANalvQZXLyV1j+EPR6Gu6cS+KVDJa/EUbbng24Y/ytJZzRXb9O9FMzyD5yRBsAnjoVx+bNK8hwhaICkBLOboZtb8OVg+DR1NhDeBDsbh6s8HpaNmEXEk29hnPX0wFwdbAlxNdTS9bT3IvARrWxrwRhUEJQzdEbJEt2XeD9TadxtLPh1aEBjOrUyLJvzalX4fPu2pf/4S1IW3vWf3KIuEtpt5xwJuvYcaKnT0eflkaj99/DfcCACjRcoahgpISzfxoF4QDUbgq9Z0OH8aUShHzi0nJMwrDvQgJnYjVhcHGwpXOzf11JQY0tIwxKCKox5+PSmbPyMAcuJTOgbV3eGhVIvVoWDupmMMAPo+DSXnhiB3i34vzB6/zx5bFbTjiTunEjV154EVvPOjT5/HOc2rSpQMMVCgsiJZzbormMYiKgdhOjIDxUJkHIJz5dE4b8IHqnY9MAcLa3NRtj8CSwkQcOdrcuDEoIqiF6g2TRzkg+3HwGJ3tb5g7zZ0QHC/cC8tmzEDa9CPd+DCFTyMvVs2zuPhycy59wRhoMxH+6kPjPPsO5UycaL5iPnZdXxduuUFgaKeH8X5ogRIdDrcaaIHR8COzKH94kMSOXMLMgeqeuacLgZG9DSDNPuvp5cndgfVrWLd/YnFpQVs04dz2NOauOcPBSMnf51+PNEe2pa+leQD7XjsKWudBmCHSeDMCBzZdIS8xmxOyO5RIBQ2YmV154kbRNm6g9ahT1576qEsIoqi9CQMs7ocUAOL9VE4TfZsOOD7XxtE4TyyUInq4ODG7fgMHttSnZmjAkmha4ffjnGerWciy3EJSERXsEQojBwCeALfCNlPKdIsrcD8wFJHBYSjmupDpv5x5Bnt7A1zsu8L8tZ3BxsGXesACGBTesvBk0uiz46g7ISoRpu8HVm9T4LJbN24dfsDeDHil7whnd1atcnj6dnFOnqTtnDp6TJ6kZQYrbCykh8m9NEC7vg1qNNEHoOAHsK+4FLikjF3s7G9wcy/f+bpUegRDCFlgI3AVEA+FCiPVSyhNmZVoBLwA9pZRJQoi6lrKnqnMmNo05Kw9zODqFwQH1eX1Ee3zcKzmK5p+vQtxJeGg1uHoDsHv1OYSAHqNalrm6rEOHuPzUDGRWFk0+/wy3vn0r2mKFwvoIAS36Q/M7IHKbtlL592dgx0f/9hAqQBDquFquF23JOUtdgHNSykgpZS7wMzC8UJlHgYVSyiQAKeV1C9pTJcnTG1j49znunb+Ty0lZfDquI58/1KnyReDsnxD2JXSdpnV7gcunEjl/MI7Og33LnHUs5ZdfuDhxEjbOzvgu/1mJgOL2RwhocQdM2QgT12sL0jbOgfkdYO8XWo+7inJTIRBCDBVClEcwGgGXzbajjfvMaQ20FkLsEkLsNbqSagynrqUy8rPdvL/pNHf512Pz0324N6gSXUH5pMfBuiehrj/cORcAvd7AjuVnqeXtRIe7Sp/hSxoMXP/wQ6489zzOHTrgu2I5ji3L3ptQKKotQkDzvjDld20hpmdz+OM5+KQD7P28SgpCaRr4scBZIcR7QohbW0V0I3ZAK6Af8CDwtRDCo3AhIcRjQogIIUREXFxcBZtQ+ej0Bhb8dZahC3ZyJTmLheM6sXB8J7zdrJBQRUpY/5SWdey+b0xd2GPbYki6mkGvMa1KnXVMn55B9FMzSPj6GzzGjqXpom9UljBFzUUI8OtjFIQN4N0K/ngePgmGPZ9VKUG46RiBlPIhIUQttIZ6qRBCAkuAn6SUaSWcGgOYv0o2Nu4zJxrYJ6XUAReEEGfQhCG8kA1fAV+BNlh8M5urMievpvLMysMcv5LK0OCGzB3qj5c1BCCfiMXacvrB70C9AAAyU3MJ+zWSpgGe+AZ5l6qa3OgYop98kpzz56n3f/9HnfHj1KCwQpGPX2/tJ2qnNqi86QUtom/PWRAyFRwqKGdIOSmVy0dKmQqsQvPzNwBGAgeEEDNKOC0caCWE8BNCOAAPAOsLlVmH1htACOGN5iqKLIP91YbcPAMfbznD0AU7iU3N5ouHOrHgwY7WFYG407DpJW0aXJfHTbv3rjtPns5ArzGtStWYZ0ZEEDVmDLpr12jy1Zd4PjReiYBCURS+vWDyBpj8O9RtC5tfgk+CYPcCyM2wmlmlGSMYJoRYC2wD7IEuUsq7gWDgv8WdJ6XMA54CNgEngRVSyuNCiNeEEMOMxTYBCUKIE8DfwBwpZcKt3FBV5PiVFIYv3MXHW84yJKgBfz7d1zRX2Grk5cLqR7Q3kRGfaTHagdgLqZzcfZXg/k1KlXAmefVqLk6Zim3t2tqgcM+elrZcoaj++PbUxg+m/KH1xDf/n+Yy2jXfKoJw03UEQohvgUVSyu1FHBsgpfzLUsYVRXVaR5CbZ+DTv8/x2d/nqOPqwJsj2jMwoL61zdL48xXY9Qk8sAzaDgFAGiSr3ttPemI241/rhoNT8Z5Dqddz/f0PSFy6FNeePWn00YfY1q5dWdYrFLcXl/ZqLqPIv8HFG3rMgNBHwNGtwi5xq+sI5gJXzSpzBupJKaMqWwSqE8diUnhm5WFOXUtjVMdGvDLUHw+XKrKaNvIf7c2j82STCACc2nuV61Gp3Dm5XYkioE9LI2b2f8nYsYM6EyZQ77lnEXZqkbpCUW6adoOJ6+DSPi0fwpZXYfd8oyA8WqGCUBSl+e9dCfQw29Yb94VaxKJqTk6engV/nePzf87j5erANxNDuNO/nrXN+pfMRFj7BHi1gEFvmXbnZOWxZ+156jevTeuuxfdaci9e5PK0J8m9dIn68+ZRZ+z9lWG1QlEzaNoVJqyFy2FaD2HLXO2lrccM6PIoOFZ8eAkonRDYGReEASClzDUO/ioKcSQ6mWdWHuZMbDqjOzfm5SH+1HYpPpFFpSMlbPgPZFyHB7eAw79jAOEbLpCVrmPojNbFDvRm7N1L9Kz/IICmixbh2rVL5ditUNQ0mnSBCWvgcri2UvmveVoP4d7/QcDICr9caYQgTggxTEq5HkAIMRyIr3BLqjE5eXo+2XKWL7dH4uPmyJLJodzRtgpGyzi0DE78AgNehYYdTbsTr2Rw9O9o/Hs1LDbrWNLPP3PtjTdx8G1Gk88/x6FJ6ReZKRSKctIkFB5aBdH7NZdRrcJrciuG0gjBE8CPQohPAYG2WniiRayphhy6nMyclYc5ez2d+0Ma89IQf2o7V6FeQD6JkbDxWWjWS5u7bERKyY4VZ7B3sqXb8BszhEmdjti33yFp2TLc+val4YcfYOtmWX+lQqEoROPOMH6lxaovzYKy80A3IYSbcTvdYtZUI7J1ev635Qxfb4+kXi0nlk4JpV+bKtgLANDrYPWjYGMLo77UfhuJPBRH9Kkk+jzQGme3gh4/fXIy0U8/TeaevXhOnUrd/85WyeQVituQUk31EEIMAQIAp3z/sZTyNQvaVaU5cCmJOSsPcz4ugwe7NOGFe9pRy6kK9gLy2f6+llFp9GKo/W92MV2unl0rz+HVyJWA3g0LnJITGcnladPIu3KVBm+9hceoivdLKhSKqsFNhUAI8QXgAtwBfAOMBsIsbFeVJFun56M/z/DNjkjq13Liu6ld6NPax9pmlcylfZoQBD8I7e8rcOhgMQln0nfsJGb2bISDA02/XYpLp06VbbVCoahEStMj6CGlDBJCHJFSzhNCfAhstLRhVY39FxOZs/IIkfEZjOvalBfubot7Ve4FAGSnwppHtNyqd79X4FBqfBYHNl2kZUhdGrXWAsNJKUn6/nti33kXx9atabLwU+wbWWZwSqFQVB1KIwTZxt+ZQoiGQAJavKEaQVaung82n2bxrgs0rO3MDw93pVer0gViszq/z4GUaG0Zu1OtAod2GRPO9LxPCxEtc3O59vrrJK9chdudA2j07rvYuN48xIRCoaj+lEYIfjWGhn4fOICWUvJrSxpVVQi7kMizqw4TlZDJhG7NeO7utuVOE1fpHF0FR36Gvs9ri1TMuHwykciDcXQd3hy3Ok7kJSURM2MmmREReD3xOD4zZyJsLJmzSKFQVCVKbNWMCWn+klImA6uFEBsAJyllSmUYZy0yc/N474/TfLsnisZ1nFn2aFd6tKgmvQCA5MuwYTY0DoU+cwoc0hLOnNESztzZhOwzZ4ie9iR5cXE0fP99ag+910pGKxQKa1GiEEgpDUKIhUBH43YOkFMZhlmLvZEJPLvqCJcSM5nUvRnPDm6La3XpBQAY9LD2cZB6GPUV2Ba0/ejf0SRdy+SeJ4PI2rmdK/99BhtXV5r98D3OQUFWMlqhUFiT0rRwfwkh7gPWyJuFKq3GZOTk8d4fp/h2z0Waerrw82Pd6Nbcy9pmlZ1dn8DFXTDicy1FnhmZqbmEb7hAU39P3MN+IfrDD3Hy96fxZwuxr1eF4iEpFIpKpTRC8DgwG8gTQmSjrS6WUspaJZ9Wfdh9Pp7nVh8hOimLKT19mTOoDS4O1agXkE/MAfj7TfAfoU0XLcQeY8KZ1pfWE7fhJ9zvHkzDt97Cxtm58m1VKBRVhtKsLLZMuLsqQHpOHu9sPMkPey/h6+XC8se608XP09pmlY/cDFjzKLjV0wJTFQocF3shlVO7r9I8+zCGv37Ce+YMvKdNU5nEFApFqRaU9Slqf1GJaqoTu87F8+yqI1xJyeLhXn48M7ANzg7VOHzCphch4TxMWg8uBcVMGiTblh7GMS+NJkeW0+jjj6k1eJCVDFUoFFWN0vg/zKedOAFdgP1Af4tYZGHSsnW8vfEUy/Zdorm3K6ue6E7nZtW0F5DPyQ2wf6kWTM7vRt0++M0W4mNtaX/9L1r+sBgnf//Kt1GhUFRZSuMaGmq+LYRoAnxsKYMsyY6zcTy/+ihXU7J4rE9zZt/VGif7atwLAEi7ButnQINguOP/ChySUnJ14VdEHKhPHZsMun/9Eg5qUFihUBSiPCOi0UC7ijbE0ny9PZI3fz9JCx9XVk3rQaemdaxt0q1jMMC6aaDLglHfgN2/0UMN2dlcffEl9p92RtekJQOe6YVDvWo4C0qhUFic0owRLEBbTQxgA3RAW2FcrbijrQ+JmbnMGtCq+vcC8tn3BZzfCkM+Ap/Wpt262OtET59OwoUEokNfwr93I+q1VCKgUCiKpjQ9ggizv/OAn6SUuyxkj8VoWded5wa3tbYZFce1Y1qC69Z3Q8hU0+6so0eJnv4U+vR0Lt77Pg7pdkUmnFEoFIp8SiMEq4BsKaUeQAhhK4RwkVJmWtY0RbHosrSpok4eMPxT01TRlN9+4+qLL2Hn7Y18bRHXNiTS54HmNyScUSgUCnNKE1nsL8B8xZEzsMUy5ihKxZa5cP2EtnrY1RtpMHD9k0+48t9ncGrfnkY//kzY7gy8GrndkHBGoVAoClMaIXAyT09p/NvFciYpSuTsFm1soOsT0OpODJmZxMz6Dwmff0Ht+0bRbMlijoankp6YQ++xrQoknFEoFIqiKI1rKEMI0UlKeQBACNEZyLKsWYoiyYjXZgn5tIM756K7coXL058i5/Rp6r3wPHUmTiQtIZsDmy/RyizhjEKhUJREaYTgP8BKIcQVtDhD9YGxljRKUQRSausFspNhwloyj50iesZMZHY2Tb74HLc+2kKy/IQzPYwJZxQKheJmlGZBWbgQoi3QxrjrtJRSZ1mzFDewfwmc/h0GvUXy3nNce/kV7Bo0oMm3S3Fs0QK4MeGMQqFQlIabOpCFENMBVynlMSnlMcBNCPGk5U1TmIg7A3+8iPTtx/WdmVx9/gWcO3fGd/nPJhEwJZzxcabDnU2sbLBCoahOlGYk8VFjhjIApJRJwKMWs0hRkLxcWPMIepyJ3ulJwqLFeDz4AE2//gq7Ov+OAeQnnOk1phV2t8uCOYVCUSmUZozAVggh8pPSCCFsATUxvbL4+01yzx4j+kgwOTHh1HvlZTzHjStQxJRwJsAL30C1glihUJSN0gjBH8ByIcSXxu3HjfsUlubCDjLXfk703sZIu0yafv0Vrj163FAsP+FM7/tbqfwCCoWizJRGCJ5Da/ynGbf/BL6xmEUKjawkkt5+jGs7vXBo2pAmX3yBg6/vDcWuXUjh1O6rdBzYFI96anmHQqEoOzcdI5BSGqSUn0spRxt/vswPN3EzhBCDhRCnhRDnhBDPF3F8shAiTghxyPjzSHlu4nZD6nRce3IU17aDa+cgfFesKFIEpEGy4+czuNR2IOSeG48rFApFaShN9NFWwNuAP1piGgCklCVGMjOOJSwE7kILXR0uhFgvpTxRqOhyKeVTZTX8dkWfmkrMo+PIOHyNOgMCqPfJjwi7oj+mk3uucv1iGndO8cfBqRrmWFYoFFWC0swaWgJ8jhZ59A7gO+CHUpzXBTgnpYyUUuYCPwPDy2toTSA3Koqo0feRceQc9Qd5UX/B8mJFICdTx95152nQojatu6hkMwqFovyURgicpZR/AUJKeVFKORcYUorzGgGXzbajjfsKc58Q4ogQYpUx+1mNJGP3bi7cPxZ93BWaDsymzrxlYFP8NNDwDVFkpevoPba1GiBWKBS3RGmEIEcIYQOcFUI8JYQYCbhV0PV/BXyllEFog9DfFlVICPGYECJCCBERFxdXQZeuOiQuW8alRx/D3s0G3wFXcX3kA/BoWmz5hCvpHNkWTUCvhvg0da9ESxUKxe1IaYRgFlq00ZlAZ+AhYFIpzosBzN/wGxv3mZBSJkgpc4yb3xjrvwEp5VdSyhApZYiPj08pLl09kDodV+fNI/a113ELaU+zHqdx6DEaAkcXf46U7Fh+FgcnW7oNb1GJ1ioUituVUsUaMv6ZDkwpQ93hQCshhB+aADwAFFgJJYRoIKW8atwcBpwsQ/3VGn1yMtH/eZrMvXvxmjwBH4efEDaN4J73Szwv8mAcMaeT6PNAa5zc7CvJWoVCcTtjsakmUso8IcRTwCbAFlgspTwuhHgNiJBSrgdmCiGGoQ1EJwKTLWVPVSLn/HkuT3uSvKtXafDO23jITXAkGqZsBKfaxZ6ny9Wzc9VZlXBGoVBUKBadcyil/B34vdC+V8z+fgF4wZI2VDXSt28nZvZ/EY6ONP3uW1zsI2HVMujzLDTtVuK5BzddJD0xh7v+668SzigUigqjNNFHe5Zmn6JkpJQkLF3K5SemYd+kCX4rV+DS3Ac2PA2NQqDvsyWenxqfZUo407CVSjijUCgqjtK8Vi4o5T5FMcjcXK6+/DLX33kX9wH98f3xB+zr14M1j4M+D0Z9BbYl+/t3rVIJZxQKhWUo1jUkhOgO9AB8hBCzzQ7VQvP5K0pBXmIi0TNnkhWxH+8np+H91FMIGxvY+T+4uBOGLwSvkmf/XD6RSOShOLqNUAlnFApFxVPSGIED2noBO8B8snoqUPz8RoWJ7NNniJ42jbyEBBp++AG1hxjX4V05CFvfBP/h0GF8iXXo9QZ2rDAmnBlQ/NoChUKhKC/FCoGU8h/gHyHEUinlRQDjwjI3KWVqZRlYXUnbupUrz8zBxtWVZj98j3NgoHYgNwNWPwquPnDvx3CTVcH5CWeGPBmErb0aIFYoFBVPaWYNvS2EeALQo60NqCWE+ERKWfKE9xqKlJKEb74h7qP/4RQQQOOFn2JfzywW0KaXIOEcTPwFXDxLrCsjJYcwY8KZZirhTIWh0+mIjo4mOzvb2qYoFBWOk5MTjRs3xt6+9OuMSiME/lLKVCHEeGAj8DywH1BCUAhDTg5XX36Z1PW/Uuueu2nw5pvYODv/W+DU71oS+h4zoXnfm9a3d9159CrhTIUTHR2Nu7s7vr6+6rkqbiuklCQkJBAdHY2fn1+pzyuNr8FeCGEPjADWSyl1gCyfmbcveXFxXJw4kdT1v+IzayYNP/ywoAikXYP1T0H9QOj/fzet79qFFE7tuUaHO5uohDMVTHZ2Nl5eXkoEFLcdQgi8vLzK3NstTY/gSyAKOAxsF0I0QxswVhjJPnGCy09OR5+SQqP5n1Br4MCCBQwGWPekNj5w3yKwcyyxPvOEM53v9rWc4TUYJQKK25XyfLdLk6FsvpSykZTyHqlxES0vgQJI3bSZqPEPgRD4LvvxRhEACPsKzv8Fg94EnzY3rTM/4UyPUS1VwhmFQmFxSrOyuJ4QYpEQYqNx25/SRR+9rZFSErdwITGzZuHUujV+K5bj1K7djQVjj8Ofr0DrwRDy8E3rVQlnFApFZVOaMYKlaIHj8qOcnQH+YyF7qgWGrCxiZs8mfsGn1B4+nKbffYtdUeGxddnaVFGnWjDs05tOFQUI23BBJZxRlBs3Ny1VyJUrVxg9Wlvuc+jQIX7//feSTiuSuXPn8sEHH1SofZagqHtWlI1ihUAIke+T8JZSrgAMoEUVRZtKWiPRxcZy8aEJpP2xibpznqHBO29j41iMz/+veXD9OAz/DNxunkchISado9tiCOjdSCWcUdwSDRs2ZNWqVUD5haC6YX7PirJRkgM6DOgEZAghvDDOFBJCdANSKsG2KkfWkSNET38KQ0YGjRcuxL1/CUMl5/6CvZ9Bl8egdRHjBoWQUrJjhTHhzLDmFWi1oiTm/XqcE1cqdu6Df8NavDo04KblRowYweXLl8nOzmbWrFk89thjuLm5MW3aNH7//XcaNGjAW2+9xbPPPsulS5f4+OOPGTZsGEuXLmXt2rWkpKQQExPDQw89xKuvvlqg7qioKO69914OHDjAK6+8QlZWFjt37uSFF17g5MmTuLm58cwzzwDQvn17NmzYgK+vL2+++SbffvstdevWpUmTJnTurOWKOn/+PNOnTycuLg4XFxe+/vpr2rZtW+R9xcXF8cQTT3Dp0iUAPv74Y3r27MncuXO5dOkSkZGRXLp0if/85z/MnDkTgO+++44PPvgAIQRBQUF8//33REVFMXXqVOLj4/Hx8WHJkiU0bdqUCxcuMG7cONLT0xk+/N806Pn3fOzYMZYuXcr69evJzMzk/PnzjBw5kvfeew+ARYsW8e677+Lh4UFwcDCOjo58+umnZfyUby9Kcg3l+yVmA+uBFkKIXWjJ62dY2rCqRsqG37g4YSLCwYFmP/9UsghkJMC6aeDTFu56rVT1nz+gJZzpOqy5SjhTQ1i8eDH79+8nIiKC+fPnk5CQQEZGBv379+f48eO4u7vzf//3f/z555+sXbuWV14xRXAnLCyM1atXc+TIEVauXElERESR13BwcOC1115j7NixHDp0iLFjxxZrz/79+/n5559NPYjw8HDTsccee4wFCxawf/9+PvjgA5588sli65k1axZPP/004eHhrF69mkceecR07NSpU2zatImwsDDmzZuHTqfj+PHjvPHGG2zdupXDhw/zySefADBjxgwmTZrEkSNHGD9+vEk0Zs2axbRp0zh69CgNGjQo1o5Dhw6xfPlyjh49yvLly7l8+TJXrlzh9ddfZ+/evezatYtTp04Ve35NoqQegXmwubVoeQUEkAPcCRyxsG1VAmkwEDd/PglffIlLSAiN5n+CnWcJK4KlhPUzICsJHloN9s7FlzWiy9Wza/VZvBq7EdCnUQVar7gZpXlztxTz589n7dq1AFy+fJmzZ8/i4ODA4MGDAQgMDMTR0RF7e3sCAwOJiooynXvXXXfh5aWtNh81ahQ7d+4kJCTkluzZsWMHI0eOxMVFW7cybNgwANLT09m9ezdjxowxlc3JySmyDoAtW7Zw4sQJ03Zqairp6ekADBkyBEdHRxwdHalbty6xsbFs3bqVMWPG4O3tDYCn8f9rz549rFmzBoAJEybw7LNaqPZdu3axevVq0/7nnnuuSDsGDBhA7dpaoid/f38uXrxIfHw8ffv2NV1jzJgxnDlzpiyP6bakJCGwRQs6V3jEssasbjJkZBDz3HOkb/kLjzGjqf/yywgHh5JP2r8UTv8GA9/UFo+VggP5CWem+GNjowaIawLbtm1jy5Yt7NmzBxcXF/r160d2djb29vamSQI2NjY4GsefbGxsyMvLM51feCJBWSYW2NnZYTAYTNs3W3xkMBjw8PDg0KFDparfYDCwd+9enJxujJTraDaeZmtrW+CeykJp7reirlUTKMk1dFVK+ZqUcl5RP5VmoZXQxcQQNW486Vv/pt6LL1D/tdduLgLxZ2HTi9C8H3QrvutsTmp8Fgc3XaJVaD2VcKYGkZKSQp06dXBxceHUqVPs3bu3TOf/+eefJCYmkpWVxbp16+jZs/hcUe7u7qSlpZm2fX19OXDgAAAHDhzgwoULAPTp04d169aRlZVFWloav/76KwC1atXCz8+PlStXAtp41uHDh4u93sCBA1mw4N+UJTcTkP79+7Ny5UoSEhIASExMBKBHjx78/PPPAPz444/07t0bgJ49exbYXxZCQ0P5559/SEpKIi8vz9SzqOmUZoygxpF54CAX7h+L7soVmnz5JZ4TJ978DSQvF1Y/oq0aHvEF2JQuUuiuVecQtoIeo1TCmZrE4MGDycvLo127djz//PN061ZymtLCdOnShfvuu4+goCDuu+++Et1Cd9xxBydOnKBDhw4sX76c++67j8TERAICAvj0009p3bo1AJ06dWLs2LEEBwdz9913Exoaaqrjxx9/ZNGiRQQHBxMQEMAvv/xS7PXmz59PREQEQUFB+Pv788UXX5R4LwEBAbz00kv07duX4OBgZs/WPNILFixgyZIlpsHj/LGDTz75hIULFxIYGEhMTEypnxlAo0aNePHFF+nSpQs9e/bE19fX5D6q0Ugpi/wBPIs7Zs2fzp07S0uStHqNPNk+UJ4dOFBmnz9f+hP/fFXKV2tJeWJ9qU+5dDxBfvr4XzJi44Uy26koPydOnLC2CbfEkiVL5PTp061tRrUlLS1NSimlTqeT9957r1yzZo2VLap4ivqOAxGymHa12NdWKWVipalRFUDq9cS+9z5XX3wR55DO+C1fjmPzUk7jjNoJOz+GjhOg3dBSnaISzigU1mHu3Ll06NCB9u3b4+fnx4gRI6xtktVRgWwAfXo6V/77DOn//EOdceOo98LziNLG8s5K0nIPe/rB4HdKfU2VcEZRXiZPnszkyZOtbQZvvvmmadwgnzFjxvDSSy9ZyaLSUR1WS1c2NV4Ici9f5vK0aeReiKL+q69Q58EHS3+ylLBhNqRfg4c3g6NbqU7LTzjTrL0XvkHe5bRcobAuL730UpVv9BWlo0YLQca+MGJmzUJKSdNF3+BaxgE7jiyH42u0/AKNOpf6tPyEM73GtCqjxQqFQlHx1FifRNLyFVx6+GFsPT3xW7G87CKQFAW/PQNNu0Ov2Tctns+1SJVwRqFQVC1qXI9A5uUR+867JP3wA669e9Poow+xdS9jgDd9Hqx5TIsmOuorsLEt3bUNkh3Lz+CqEs4oFIoqRI0SAn1KCjFPzyZj9248J02i7rNzELala8QLsONDuLwPRn0DHqWf8ZOfcObOKf4q4YxCoagy1BjXUM6FC0SNfYCM8HAavPG6NjOoPCJwORz+eRcC74egMTcvn3/9/IQzLVXCGUXFERUVRfv27a1txk2ZPHmyKUT0I488UiAWkcL61JjX0vRt/6BPSaHZksW4lDc4V04arHkEajWCIWWbgha24QLZ6Tp6z1QJZxQ1m2+++cbaJigKUWOEwHPyJGoPvRc771uYrrnxOUi+BJN/A6fSL0vPTzjj37sRPk1Uwpkqxcbn4drRiq2zfiDcffM1JcXlI5g1axYbNmzA2dmZX375hXr16nH+/HnGjx9PRkYGw4cP5+OPPzZF9MxHr9fz/PPPs23bNnJycpg+fTqPP/54sdd///33WbFiBTk5OYwcOZJ58+YRFRXF3XffTa9evdi9ezeNGjXil19+wdnZmXPnzvHEE08QFxeHra0tK1eupHnz5jz77LNs3LgRIQT/93//x9ixY5FSMmPGDP7880+aNGmCg1mcrn79+vHBBx8QEhJyS/erqDhqjGtICHFrInB8LRz6EXr/F5r1KPVpUkp2rDiDg7NKOKMoSHH5CLp168bhw4fp06cPX3/9NaDF4J81axZHjx6lcePGRda3aNEiateuTXh4OOHh4Xz99demgHKF2bx5M2fPniUsLIxDhw6xf/9+tm/fDsDZs2eZPn06x48fx8PDwxSYbfz48UyfPp3Dhw+ze/duGjRowJo1azh06BCHDx9my5YtzJkzh6tXr7J27VpOnz7NiRMn+O6779i9e3eRdtzK/SoqjhrTI7glUqLh11naWoG+Rcc+Lw4t4UwyfR9srRLOVEVK8eZuKYrLR3DvvfcC0LlzZ/78809Ai82/bt06AMaNG2fKLmbO5s2bOXLkiMkXn5KSwtmzZ/Hz8yuy7ObNm+nYsSOg5Rw4e/YsTZs2xc/Pjw4dOphsiIqKIi0tjZiYGEaOHAlgCjG9c+dOHnzwQWxtbalXrx59+/YlPDyc7du3m/Y3bNiQ/v37F/kMbuV+FRWHEoKbYTDA2ie0KaOjvgbb0jfm5gln/HurhDOKfylNPoKyxtCXUrJgwQIGDRpUqrIvvPDCDa6jqKioG+L4Z2VlldqGsnIr96uoOCzqGhJCDBZCnBZCnBNCPF9CufuEEFIIcWsplizBngUQtQPufhe8WpTp1AN/aAln+oxtrRLOKApQ1nwE3bp1M7lo8mPxF2bQoEF8/vnn6HQ6AM6cOUNGRkaxZRcvXmzyu8fExHD9+vVir+/u7k7jxo1Nb+k5OTlkZmbSu3dvli9fjl6vJy4uju3bt9OlSxf69Olj2n/16lX+/vvvEu+vPPerqDgsJgRCCFtgIXA34A88KITwL6KcOzAL2GcpW8rNlUPw1+taRNGOD5Xp1NT4LA5uzk8442ER8xTVl7LmI/j444/56KOPCAoK4ty5c0XG0H/kkUfw9/enU6dOtG/fnscff7zYN+yBAwcybtw4unfvTmBgIKNHjy6QvKYovv/+e+bPn09QUBA9evTg2rVrjBw5kqCgIIKDg+nfvz/vvfce9evXZ+TIkbRq1Qp/f38mTpxI9+7dS/9wSnm/igqkuPjUt/oDdAc2mW2/ALxQRLmPgSHANiDkZvVaOh+BiZwMKed3lvKDNlJmJJT59N8+Oyy/mLlNpiVmW8A4xa1QHfMRZGRkSIPBIKWU8qeffpLDhg2zskWWpabdb0VT1nwElhwjaARcNtuOBrqaFxBCdAKaSCl/E0LMsaAtZWfz/0HCWZiwDlxKSFZfBJdOJHDhcDzdRjTHrY7jzU9QKG7C/v37eeqpp5BS4uHhweLFi61tkkWpafdrbaw2WCyEsAE+AiaXouxjwGMATZtWQhKX0xshYhF0fwpa3FGmU/V5BnauOEttlXBGUYH07t27xDzBxXH06FEmTJhQYJ+joyP79lU9T6w55b1fRfmwpBDEAE3Mthsb9+XjDrQHthlnDdQH1gshhkkpI8wrklJ+BXwFEBISIi1oM6TFwi/ToV4gDHilzKcfyU84M10lnFFYn8DAwJsmj1coLNlShQOthBB+QggH4AFgff5BKWWKlNJbSukrpfQF9gI3iEClIiX88iTkZsB932iJ6MtARkoO4b9doFmgF76BKuGMQqGoHlhMCKSUecBTwCbgJLBCSnlcCPGaEGKYpa57S4R9Bee2wMA3oG7bMp++d+159HkGeo1WCWcUCkX1waJjBFLK34HfC+0r0t8ipexnSVtuyvWTsPllaDUQQh8p8+nXIlM4tfcanQY1UwlnFApFtUI5sQF02bD6EXB0h+ELtYQzZaBgwplmFjJSoVAoLIMSAoC/XoPYYzDiM3CrW+bTT+7WEs70uK+lSjijqFS2bdtmitWzfv163nnn1mMnLV26lCtXrpS5XHXPM+Dm5gbAlStXGD16tJWtqVyUEJzfCnsXau6g1jeP0VKYnEwde4wJZ1qFqoQzCusxbNgwnn++2EguBSgppk95heCbb77B3/+G4AHVjoYNG5oC99UUavbra0YCrJ0G3m3grtfLVUXYrxfIydDRe6xKOFMdeTfsXU4lnqrQOtt6tuW5LiVHqY2KimLw4MF07tyZAwcOEBAQwHfffccHH3zAr7/+SlZWFj169ODLL79ECFEghn98fDwhISFERUUVqHPp0qVERETw6aefFnnNyZMn4+TkxMGDB+nZsycTJ07kiSeeIDMzkxYtWrB48WL++usvIiIiGD9+PM7OzuzZs4f333//BptWr159Q7m7777bZONPP/3EW2+9hZSSIUOG8O677wIUm3+gKOLi4njiiSe4dOkSoIWd6NmzJ3PnzuXSpUtERkZy6dIl/vOf/zBz5kwA0zMUQhAUFMT3339PVFQUU6dOJT4+Hh8fH5YsWULTpk25cOEC48aNIz09neHDhxf4bO69916OHTvG0qVLWb9+PZmZmZw/f56RI0fy3nvvAVrY73fffRcPDw+Cg4NxdHQs9tlXdWpuj0BK+HUmZCZoU0Udyj7AmxCTztF/YghQCWcU5eD06dM8+eSTnDx5klq1avHZZ5/x1FNPER4ezrFjx8jKymLDhg0Ves3o6Gh2797NRx99xMSJE3n33Xc5cuQIgYGBzJs3j9GjRxMSEsKPP/7IoUOHcHZ2LtKmosrlc+XKFZ577jm2bt3KoUOHCA8PNwWrKy7/QFHMmjWLp59+mvDwcFavXs0jj/w7iePUqVNs2rSJsLAw5s2bh06n4/jx47zxxhts3bqVw4cP88knnwAwY8YMJk2axJEjRxg/frxJNGbNmsW0adM4evQoDRo0KNaOQ4cOsXz5co4ePcry5cu5fPkyV65c4fXXX2fv3r3s2rWLU6cq9mWisqm5PYID38GpDVpPoEFQmU+XZglnuqqEM9WWm725W5ImTZrQs2dPAB566CHmz5+Pn58f7733HpmZmSQmJhIQEMDQoUMr7JpjxozB1taWlJQUkpOT6du3LwCTJk1izJiic3D//fffZbIpPDycfv364ePjA2gJbbZv386IESOKzT9QFFu2bCkw5pCammqKljpkyBAcHR1xdHSkbt26xMbGsnXrVsaMGYO3MQGVp6cWGmbPnj2sWbMGgAkTJvDss88CsGvXLlOE0wkTJvDcc0V/FwYMGGAKeufv78/FixeJj4+nb9++pmuMGTOGM2fOFHsvVZ2aKQTx5+CP58GvjxZGohyohDOKW6WwK1EIwZNPPklERARNmjRh7ty5ZGdnA2BnZ4fBYAAw7SsPrq6uZSqfnZ1drE3loSz5BwwGA3v37jUlwTGncM6E8uYxKI07t6KuVZWpea4hvU5LQG/rACO/BJuyPwJdrp5dq1TCGcWtcenSJfbs2QPAsmXL6NWrFwDe3t6kp6cXGLD09fVl//79ABUykFm7dm3q1KnDjh07AC3EdH7vwN3d3RSSOr/RL8om83LmdOnShX/++Yf4+Hj0ej0//fSTqe6yMHDgQBYsWGDavlmojP79+7Ny5UoSEhIASExMBKBHjx6mnAY//vgjvXv3BqBnz54F9peF0NBQ/vnnH5KSksjLyzP1LKorNU8Itr0NVw7CsPlQq2G5qjjwx0XSk1TCGcWt0aZNGxYuXEi7du1ISkpi2rRpPProo7Rv355BgwYRGhpqKvvMM8/w+eef07FjR+Lj4yvk+t9++y1z5swhKCiIQ4cO8cor2lrPyZMn88QTT9ChQwccHR2Ltcm8nHkWswYNGvDOO+9wxx13EBwcTOfOnQsMxpaW+fPnExERQVBQEP7+/nzxxRcllg8ICOCll16ib9++BAcHM3v2bAAWLFjAkiVLTIPH+WMHn3zyCQsXLiQwMJCYmJiSqr6BRo0a8eKLL9KlSxd69uyJr69vtc6ZILQw1dWHkJAQGRFRznBEUbtg6RDoOF5bOFYOUuKy+GnePpp39GHgwwHls0NhVU6ePEm7du2saoP5zBRF9SQ9PR03Nzfy8vIYOXIkU6dONeV0tjZFfceFEPullEVmgaw5PYKsZFj7OHj6weB3y13NrlVnEbaCHqNaVpxtCoWi2jF37lw6dOhA+/bt8fPzY8SIEdY2qdzUnMHi3fMh9Qo8vBkc3cpVhUo4o6gofH19LdYbePPNN1m5cmWBfWPGjOGll16yyPVulepmbz4ffPCBtU2oMGqOaygvBy7tgeb9ynVdfZ6Bn18PQxokD77SVeUaqMZUBdeQQmFJlGuoOOwcyy0CoCWcSY7NpNf9rZQIKBSK2wrVopUClXBGoVDczighKAWmhDNjVMIZhUJx+6GE4CbkJ5zpMKApHnVVwhmFQnH7oYSgBAwGyfafVcIZRcWTH/se4Pjx4/Tv3582bdrQokULXn31VVM4iaVLl+Lj40OHDh3w9/cvMUhbZePr62ta3NajRw8rW6O4FWrO9NFycGr3VeIupXHXVH+VcOY25dpbb5FzsmIjRzq2a0v9F18sVdmsrCyGDRvG559/zsCBA8nMzOS+++7jk08+4emnnwZg7NixfPrpp1y/fp2AgACGDRtWbOhma7F7925rm6C4BVSPoBiyM1TCGYXlWbZsGT179mTgwIEAuLi48Omnn/L+++/fULZu3bq0aNGCixcvFllXRkYGU6dOpUuXLnTs2JFffvkF0HoVo0aNYvDgwbRq1coUfRPgjz/+oFOnTgQHBzNgwABAi9EzYsQIgoKC6NatG0eOHAEgISGBgQMHEhAQwCOPPIL51PP8Hs62bdvo168fo0ePpm3btowfP95U7vfff6dt27Z07tyZmTNnmqKQKqyPes0thvANKuFMTaC0b+6W4vjx43Tu3LnAvhYtWpCVlUVycnKB/ZGRkURGRtKyZdGr2t9880369+/P4sWLSU5OpkuXLtx5552AFrDt4MGDODo60qZNG2bMmIGTkxOPPvoo27dvx8/PzxSk7dVXX6Vjx46sW7eOrVu3MnHiRA4dOsS8efPo1asXr7zyCr/99huLFi0q0o6DBw9y/PhxGjZsSM+ePdm1axchISE8/vjjpms9+OCDt/jkFBWJEoIiUAlnFFWJ5cuXs3PnThwdHfnyyy9NMfALs3nzZtavX29a8ZqdnW3K7lVUTP2kpCT69OmDn58f8G/8/p07d5qiafbv35+EhARSU1PZvn27Ka7/kCFDqFOnTpF2dOnShcaNGwPQoUMHoqKicHNzo3nz5qZrPfjgg3z11Ve3/GwUFYMSgkJIKdmxXCWcUVQO/v7+bN++vcC+yMhIvLy88PDwAP4dI7gZUkpWr15NmzZtCuzft29fpcbUrwnx+2831BhBIc4fiCPmTDLdhrdQCWcUFmf8+PHs3LmTLVu2ANrg8cyZM5k3b16Z6xo0aBALFiww+eQPHjxYYvlu3bqxfft2Lly4APwbv793796m+Pzbtm3D29ubWrVq0adPH5YtWwbAxo0bSUpKKrVtbdq0ITIy0pRnefny5WW6N4VlUUJghi5HSzjj3cQN/17ly1WgUJQFZ2dn1q9fz5tvvknr1q3x9vamZ8+ejB8/vsx1vfzyy+h0OoKCgggICODll18usbyPjw9fffUVo0aNIjg4mLFjxwJaVM39+/cTFBTE888/z7fffgtoYwfbt28nICCANWvW0LRp0zLd52effcbgwYPp3Lkz7u7u1Tp+/+1GzQk6Vwr2rY8k4vcoRj7TiYYtPSxyDYX1qcpB59atW8fs2bP5+++/adbs9lq7kh+/X0rJ9OnTadWqlWmKrKJiUUHnyklKXBYHN1+iVWg9JQIKqzFixAgiIyNvOxEA+Prrr+nQoQMBAQGkpKTw+OOPW9skhRE1WGxEJZxRVBeWLFliSreYT8+ePVm4sHxZ9yqLp59+WvUAqihKCIBLx7WEM91HtlAJZxRVnilTpjBlyhRrm6G4jajxriF9noEdK85Su64zwf2bWNschUKhqHRqvBAc2WpMODNGJZxRKBQ1kxrd8uUnnPFVCWcUCkUNpkYLwZ6159HrDfRUCWcUCkUNpsYKwdXzKZzee40Od6qEM4rbm8mTJ7Nq1SqrXX/btm0WC1Nd1nuLioqiffv2FrGlPPTr14/8dVH33HPPDYEGKwuLzhoSQgwGPgFsgW+klO8UOv4EMB3QA+nAY1LKE5a0CbSEMzuWn8HVw5HOg2+/+dqK0rNjxRniL6dXaJ3eTdzofX/rCq2zOrNt2zbc3NxU8pqb8Pvvv1vt2hbrEQghbIGFwN2AP/CgEMK/ULFlUspAKWUH4D3gI0vZY87JXVeIu5RGj/taqIQzCqvx3XffERQURHBwMBMmTCAqKor+/fsTFBTEgAEDTJFDJ0+ezLRp0+jWrRvNmzdn27ZtTJ06lXbt2jF58mRTfW5ubjz99NMEBAQwYMAA4uLibrjm/v376du3L507d2bQoEFcvXqVlJQU2rRpw+nTpwEtMmhJmdA2b95M9+7d6dSpE2PGjCE9XRNSX19fXn31VTp16kRgYCCnTp0iKiqKL774gv/973906NCBHTt28Ouvv9K1a1c6duzInXfeSWxsLKCFtpg6dSr9+vWjefPmzJ8/33TN119/nTZt2tCrVy8efPBBU4TVm91b/v7g4GCCg4NvutZCr9czZ84cQkNDCQoK4ssvvwRKzrMQHh5Ojx49CA4OpkuXLqSlpZGdnc2UKVMIDAykY8eO/P3334AWS+qBBx6gXbt2jBw5kqysLNO18zO+RUVF0a5dOx599FECAgIYOHCgqVx4eDhBQUF06NCBOXPmVFzvRkppkR+gO7DJbPsF4IUSyj8IbLxZvZ07d5a3QlZ6rvzmv9vl6vcjpMFguKW6FNWTEydOWNsEeezYMdmqVSsZFxcnpZQyISFB3nvvvXLp0qVSSikXLVokhw8fLqWUctKkSXLs2LHSYDDIdevWSXd3d3nkyBGp1+tlp06d5MGDB6WUUgLyhx9+kFJKOW/ePDl9+nTT+StXrpS5ubmye/fu8vr161JKKX/++Wc5ZcoUKaWUmzdvlt26dZM//fSTHDRoULF2x8XFyd69e8v09HQppZTvvPOOnDdvnpRSymbNmsn58+dLKaVcuHChfPjhh6WUUr766qvy/fffN9WRmJho+t/7+uuv5ezZs03lunfvLrOzs2VcXJz09PSUubm5MiwsTAYHB8usrCyZmpoqW7ZsaaqvNPcWGBgo//nnHymllM8884wMCAgo9v6+/PJL+frrr0sppczOzpadO3eWkZGR8u+//5a1atWSly9flnq9Xnbr1k3u2LFD5uTkSD8/PxkWFiallDIlJUXqdDr5wQcfmK5/8uRJ2aRJE5mVlSU//PBD0/7Dhw9LW1tbGR4ebnp+cXFx8sKFC9LW1tb0uY4ZM0Z+//33UkopAwIC5O7du6WUUj733HPF3ktR33EgQhbTrlrydbgRcNlsOxroWriQEGI6MBtwAPoXVZEQ4jHgMaBMga6KIsyYcKbPAyrhjMJ6bN26lTFjxuDtrc1W8/T0ZM+ePaZ4/xMmTCiQSWzo0KEIIQgMDKRevXoEBgYCEBAQQFRUFB06dMDGxsYUOO6hhx5i1KhRBa55+vRpjh07xl133QVob78NGjQA4K677mLlypVMnz6dw4cPF2v33r17OXHiBD179gQgNzeX7t27m47nX7Nz586meylMdHQ0Y8eO5erVq+Tm5ppyFICW58DR0RFHR0fq1q1LbGwsu3btYvjw4Tg5OeHk5MTQoUNvqLO4e0tOTiY5OZk+ffqYnuvGjRuLvb/Nmzdz5MgR07hDSkoKZ8+excHBocg8C7Vr16ZBgwaEhoYCUKtWLUDL6TBjxgwA2rZtS7NmzThz5gzbt29n5syZAAQFBREUFFSkHX5+fnTo0MH0LKOiokhOTiYtLc30vMeNG8eGDRuKvZeyYHW/iJRyIbBQCDEO+D9gUhFlvgK+Ai3oXHmvlRCTzrF/Ygjo0wjvxirhjKL6kB/j38bGpkC8fxsbm2Lj/Rd+0ZFSEhAQwJ49e24oazAYOHnyJC4uLiQlJZkavMJIKbnrrrv46aefSrSzpDwEM2bMYPbs2QwbNoxt27Yxd+7cG86/WR1F2VXUvZV18FVKyYIFCxg0aFCB/du2bbNqTgdzF5IlsOSsoRjAfKluY+O+4vgZGGEpY6R5wpmhKuGMwrr079+flStXkpCQAGi5AHr06MHPP/8MwI8//kjv3r3LVKfBYDC9yS5btoxevXoVON6mTRvi4uJMjaVOp+P48eMA/O9//6Ndu3YsW7aMKVOmoNPpirxGt27d2LVrF+fOnQO0PMlnzpwp0S53d3fS0tJM2ykpKTRq1AjAFOK6JHr27Mmvv/5KdnY26enpRb4FF3dvHh4eeHh4sHPnTgBTnoXiGDRoEJ9//rnp/s+cOUNGRkax5du0acPVq1cJDw8HIC0tjby8vAI5Hc6cOcOlS5do06ZNgZwOx44dM+WDLg0eHh64u7uzb98+ANN3pSKwZI8gHGglhPBDE4AHgHHmBYQQraSUZ42bQ4CzWIhz+68TcyaZvuPaqIQzCqsTEBDASy+9RN++fbG1taVjx44sWLCAKVOm8P777+Pj48OSJUvKVKerqythYWG88cYb1K1b94bkLw4ODqxatYqZM2eSkpJCXl4e//nPf7Czs+Obb74hLCwMd3d3+vTpwxtvvFFkchwfHx+WLl3Kgw8+SE5ODgBvvPEGrVsXP0tq6NChjB49ml9++YUFCxYwd+5cxowZQ506dejfv78pMU5xhIaGMmzYMIKCgkxuscK5DIq7t4CAAJYsWcLUqVMRQjBw4MASr/XII48QFRVFp06dkFLi4+PDunXrii3v4ODA8uXLmTFjBllZWTg7O7NlyxaefPJJpk2bRmBgIHZ2dixduhRHR0emTZvGlClTaNeuHe3atbshX/XNWLRoEY8++ig2Njb07du3wnI6WDQfgRDiHuBjtOmji6WUbwohXkMbtFgvhPgEuBPQAUnAU1LK4yXVWd58BBePJXB8RwyDHw/ExkaNDdRkqnI+glvBzc3NNIPndiM/l0FmZiZ9+vThq6++olOnTtY2q9LJfw4A77zzDlevXr0hEi2UPR+BRccIpJS/A78X2veK2d+zLHl9c5q196JZe6/KupxCoahAHnvsMU6cOEF2djaTJk2qkSIA8Ntvv/H222+Tl5dHs2bNWLp0aYXUa/XBYoVCUTFUdG+ga9euJvdPPt9//71pxlJlku9Xryg2bdrEc889V2Cfn58fa9eurdDrVDRjx441zQyrSJQQKGokUko1ffgm5A9K3o4MGjTohplBtwvlcffX2FhDipqLk5MTCQkJ5fqHUSiqMlJKEhIScHJyKtN5qkegqHE0btyY6OjoIkMwKBTVHScnp2LXgRSHEgJFjcPe3r7AalaFoqajXEMKhUJRw1FCoFAoFDUcJQQKhUJRw7HoymJLIISIAy6W83RvIL4CzbEm6l6qHrfLfYC6l6rKrdxLMymlT1EHqp0Q3ApCiIjillhXN9S9VD1ul/sAdS9VFUvdi3INKRQKRQ1HCYFCoVDUcGqaEHxlbQMqEHUvVY/b5T5A3UtVxSL3UqPGCBQKhUJxIzWtR6BQKBSKQighUCgUihpOjRECIcRgIcRpIcQ5IcTz1ranvAghFgshrgshjlnblltBCNFECPG3EOKEEOK4EKLSkhRVNEIIJyFEmBDisPFebszxWM0QQtgKIQ4KIW5MEFyNEEJECSGOCiEOCSHKntqwiiCE8BBCrBJCnBJCnBRCdK/Q+mvCGIEQwhY4A9wFRKPlU35QSnnCqoaVAyFEHyAd+E5K2d7a9pQXIUQDoIGU8oAQwh3YD4yopp+JAFyllOlCCHtgJzBLSrnXyqaVGyHEbCAEqCWlvNfa9pQXIUQUECKlrNYLyoQQ3wI7pJTfCCEcABcpZXJF1V9TegRdgHNSykgpZS7wMzDcyjaVCynldiDR2nbcKlLKq1LKA8a/04CTQCPrWlU+pEZ+ejB740+1fcMSQjQGhgDfWNsWBQghagN9gEUAUsrcihQBqDlC0Ai4bLYdTTVtdG5HhBC+QEeg2qbEMrpSDgHXgT+llNX2XoCPgWcBg5XtqAgksFkIsV8I8Zi1jSknfkAcsMTorvtGCOFakReoKUKgqKIIIdyA1cB/pJSp1ranvEgp9VLKDkBjoIsQolq67YQQ9wLXpZT7rW1LBdFLStkJuBuYbnStVjfsgE7A51LKjkAGUKHjnDVFCGKAJmbbjY37FFbE6E9fDfwopVxjbXsqAmOX/W9gsJVNKS89gWFG3/rPQH8hxA/WNan8SCljjL+vA2vR3MTVjWgg2qyXuQpNGCqMmiIE4UArIYSfcaDlAWC9lW2q0RgHWBcBJ6WUH1nbnltBCOEjhPAw/u2MNinhlFWNKidSyheklI2llL5o/ydbpZQPWdmsciGEcDVORMDoShkIVLvZdlLKa8BlIUQb464BQIVOqqgRqSqllHlCiKeATYAtsFhKedzKZpULIcRPQD/AWwgRDbwqpVxkXavKRU9gAnDU6FsHeFFK+bv1TCo3DYBvjbPTbIAVUspqPe3yNqEesFZ758AOWCal/MO6JpWbGcCPxhfZSGBKRVZeI6aPKhQKhaJ4aoprSKFQKBTFoIRAoVAoajhKCBQKhaKGo4RAoVAoajhKCBQKhaKGo4RAUWMRQqQbf/sKIcZVcN0vFtreXZH1KxQViRIChQJ8gTIJgRDiZmtwCgiBlLJHGW1SKCoNJQQKBbwD9DbGrH/aGEDufSFEuBDiiBDicQAhRD8hxA4hxHqMKzuFEOuMAc2O5wc1E0K8Azgb6/vRuC+/9yGMdR8zxskfa1b3NrOY8z8aV18rFBanRqwsVihuwvPAM/lx940NeoqUMlQI4QjsEkJsNpbtBLSXUl4wbk+VUiYaQ0uECyFWSymfF0I8ZQxCV5hRQAcgGPA2nrPdeKwjEABcAXahrb7eWdE3q1AURvUIFIobGQhMNIa+2Ad4Aa2Mx8LMRABgphDiMLAXLbBhK0qmF/CTMVppLPAPEGpWd7SU0gAcQnNZKRQWR/UIFIobEcAMKeWmAjuF6IcWAth8+06gu5QyUwixDXC6hevmmP2tR/1/KioJ1SNQKCANcDfb3gRMM4bJRgjRuphEILWBJKMItAW6mR3T5Z9fiB3AWOM4hA9a5qmwCrkLhaKcqDcOhQKOAHqji2cp8AmaW+aAccA2DhhRxHl/AE8IIU4Cp9HcQ/l8BRwRQhyQUo43278W6A4cRsue9ayU8ppRSBQKq6CijyoUCkUNR7mGFAqFooajhEChUChqOEoIFAqFooajhEChUChqOEoIFAqFooajhEChUChqOEoIFAqFoobz//tDGY3Ai8SWAAAAAElFTkSuQmCC",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# Benchmarking different encoding methods\n",
"x=[2*i for i in range(len(acc_list[0]))]\n",
"for i in range(len(encoding_list)):\n",
" plt.plot(x,acc_list[i])\n",
"plt.legend(encoding_list)\n",
"plt.title(\"Benchmarking different encoding methods\")\n",
"plt.xlabel(\"Iteration\")\n",
"plt.ylabel(\"Test accuracy\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Quantum Classification on Built-In MNIST and Iris Datasets\n",
"\n",
"Paddle Quantum provides datasets commonly used in quantum classification tasks, and users can use the `paddle_quantum.dataset` module to get the encoding circuits or encoded states. There are four built-in datasets in Paddle Quantum at present, including MNIST, FashionMNIST, Iris and BreastCancer. We can easily accomplishing quantum classification using these quantum datasets.\n",
"\n",
"The first case is Iris. It has three types of labels and 50 samples of each type. There are only four features in Iris data, and it is very easy to fulfill its classification."
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\Users\\yeruilin\\Anaconda3\\envs\\paddle_quantum_env\\lib\\site-packages\\paddle\\fluid\\dygraph\\math_op_patch.py:237: UserWarning: The dtype of left and right variables are not the same, left dtype is paddle.float64, but right dtype is paddle.int32, the right dtype will convert to paddle.float64\n",
" warnings.warn(\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"epoch: 0 iter: 0 loss: 0.3113 train acc: 0.0000 test acc: 0.0000\n",
"epoch: 0 iter: 5 loss: 0.4818 train acc: 0.0000 test acc: 0.3500\n",
"epoch: 0 iter: 10 loss: 0.2171 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 0 iter: 15 loss: 0.1688 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 1 iter: 0 loss: 0.1350 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 1 iter: 5 loss: 0.1110 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 1 iter: 10 loss: 0.0879 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 1 iter: 15 loss: 0.0490 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 2 iter: 0 loss: 0.0733 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 2 iter: 5 loss: 0.0740 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 2 iter: 10 loss: 0.0660 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 2 iter: 15 loss: 0.0394 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 3 iter: 0 loss: 0.0654 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 3 iter: 5 loss: 0.0557 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 3 iter: 10 loss: 0.0602 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 3 iter: 15 loss: 0.0397 train acc: 1.0000 test acc: 1.0000\n"
]
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# Using Iris\n",
"test_rate = 0.2\n",
"num_qubit = 4\n",
"\n",
"# acquire Iris data as quantum states\n",
"iris =Iris (encoding='angle_encoding', num_qubits=num_qubit, test_rate=test_rate,classes=[0, 1], return_state=True)\n",
"\n",
"quantum_train_x, train_y = iris.train_x, iris.train_y\n",
"quantum_test_x, test_y = iris.test_x, iris.test_y\n",
"testing_data_num = len(test_y)\n",
"training_data_num = len(train_y)\n",
"\n",
"acc = QClassifier2(\n",
" quantum_train_x, # training x\n",
" train_y, # training y\n",
" quantum_test_x, # testing x\n",
" test_y, # testing y\n",
" N = num_qubit, # Number of qubits required\n",
" DEPTH = 1, # Circuit depth\n",
" EPOCH = 4, # Number of training epochs, the total iteration number \"EPOCH * (Ntrain / BATCH)\" is chosen to be about 200\n",
" LR = 0.1, # Set the learning rate\n",
" BATCH = 4, # Batch size during training\n",
" )\n",
"plt.plot(acc)\n",
"plt.title(\"Classify Iris 0&1 using angle encoding\")\n",
"plt.xlabel(\"Iteration\")\n",
"plt.ylabel(\"Testing accuracy\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The second case is MNIST. It is a handwritten digit dataset and has 10 classes. Each figure has $28\\times28$ pixels, and downscaling methods such as ``resize`` and ``PCA`` should be used to transform it into the target dimension."
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"epoch: 0 iter: 0 loss: 0.3237 train acc: 0.3250 test acc: 0.5450\n",
"epoch: 0 iter: 5 loss: 0.2124 train acc: 0.7500 test acc: 0.6500\n",
"epoch: 0 iter: 10 loss: 0.2294 train acc: 0.6500 test acc: 0.6850\n",
"epoch: 1 iter: 0 loss: 0.1970 train acc: 0.7250 test acc: 0.7850\n",
"epoch: 1 iter: 5 loss: 0.1521 train acc: 0.8500 test acc: 0.8150\n",
"epoch: 1 iter: 10 loss: 0.1726 train acc: 0.7750 test acc: 0.8900\n",
"epoch: 2 iter: 0 loss: 0.1742 train acc: 0.7250 test acc: 0.8650\n",
"epoch: 2 iter: 5 loss: 0.1167 train acc: 0.9000 test acc: 0.8900\n",
"epoch: 2 iter: 10 loss: 0.1654 train acc: 0.8000 test acc: 0.8950\n",
"epoch: 3 iter: 0 loss: 0.1609 train acc: 0.8000 test acc: 0.8850\n",
"epoch: 3 iter: 5 loss: 0.1148 train acc: 0.9250 test acc: 0.8850\n",
"epoch: 3 iter: 10 loss: 0.1649 train acc: 0.8000 test acc: 0.8750\n",
"epoch: 4 iter: 0 loss: 0.1629 train acc: 0.8250 test acc: 0.8750\n",
"epoch: 4 iter: 5 loss: 0.1112 train acc: 0.9000 test acc: 0.8700\n",
"epoch: 4 iter: 10 loss: 0.1630 train acc: 0.8500 test acc: 0.8850\n"
]
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# using MNIST\n",
"\n",
"# main parameters\n",
"training_data_num = 500\n",
"testing_data_num = 200\n",
"qubit_num = 4\n",
"\n",
"# MNIST data with amplitude encoding, resized to 4*4\n",
"train_dataset = MNIST(mode='train', encoding='amplitude_encoding', num_qubits=qubit_num, classes=[3, 6],\n",
" data_num=training_data_num, need_cropping=True,\n",
" downscaling_method='resize', target_dimension=16, return_state=True)\n",
"\n",
"val_dataset = MNIST(mode='test', encoding='amplitude_encoding', num_qubits=qubit_num, classes=[3, 6],\n",
" data_num=testing_data_num, need_cropping=True,\n",
" downscaling_method='resize', target_dimension=16,return_state=True)\n",
"\n",
"quantum_train_x, train_y = train_dataset.quantum_image_states, train_dataset.labels\n",
"quantum_test_x, test_y = val_dataset.quantum_image_states, val_dataset.labels\n",
"\n",
"acc = QClassifier2(\n",
" quantum_train_x, # Training x\n",
" train_y, # Training y\n",
" quantum_test_x, # Testing x\n",
" test_y, # Testing y\n",
" N = qubit_num, # Number of qubits required\n",
" DEPTH = 3, # Circuit depth\n",
" EPOCH = 5, # Number of training epochs, the total iteration number \"EPOCH * (Ntrain / BATCH)\" is chosen to be about 200\n",
" LR = 0.1, # Set the learning rate\n",
" BATCH = 40, # Batch size during training\n",
" )\n",
"\n",
"plt.plot(acc)\n",
"plt.title(\"Classify MNIST 3&6 using amplitude encoding\")\n",
"plt.xlabel(\"Iteration\")\n",
"plt.ylabel(\"Testing accuracy\")\n",
"plt.show()"
]
},
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
...@@ -1020,7 +1408,9 @@ ...@@ -1020,7 +1408,9 @@
"\n", "\n",
"[2] Farhi, Edward, and Hartmut Neven. Classification with quantum neural networks on near term processors. [arXiv preprint arXiv:1802.06002 (2018).](https://arxiv.org/abs/1802.06002)\n", "[2] Farhi, Edward, and Hartmut Neven. Classification with quantum neural networks on near term processors. [arXiv preprint arXiv:1802.06002 (2018).](https://arxiv.org/abs/1802.06002)\n",
"\n", "\n",
"[3] Schuld, Maria, et al. Circuit-centric quantum classifiers. [Physical Review A 101.3 (2020): 032308.](https://arxiv.org/abs/1804.00633)\n" "[3] Schuld, Maria, et al. Circuit-centric quantum classifiers. [Physical Review A 101.3 (2020): 032308.](https://arxiv.org/abs/1804.00633)\n",
"\n",
"[4] Schuld, Maria. Supervised quantum machine learning models are kernel methods. [arXiv preprint arXiv:2101.11020 (2021).](https://arxiv.org/pdf/2101.11020)"
] ]
} }
], ],
...@@ -1040,7 +1430,7 @@ ...@@ -1040,7 +1430,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.7.11" "version": "3.8.12"
}, },
"toc": { "toc": {
"base_numbering": 1, "base_numbering": 1,
......
...@@ -919,7 +919,7 @@ ...@@ -919,7 +919,7 @@
"\n", "\n",
"## 参考文献\n", "## 参考文献\n",
"\n", "\n",
"[1] Wang, X., Song, Z. & Wang, Y. Variational Quantum Singular Value Decomposition. [arXiv:2006.02336 (2020).](https://arxiv.org/abs/2006.02336)" "[1] Wang, X., Song, Z., & Wang, Y. Variational Quantum Singular Value Decomposition. [Quantum, 5, 483 (2021).](https://quantum-journal.org/papers/q-2021-06-29-483/)"
] ]
} }
], ],
......
...@@ -921,7 +921,7 @@ ...@@ -921,7 +921,7 @@
"\n", "\n",
"## References\n", "## References\n",
"\n", "\n",
"[1] Wang, X., Song, Z. & Wang, Y. Variational Quantum Singular Value Decomposition. [arXiv:2006.02336 (2020).](https://arxiv.org/abs/2006.02336)" "[1] Wang, X., Song, Z., & Wang, Y. Variational Quantum Singular Value Decomposition. [Quantum, 5, 483 (2021).](https://quantum-journal.org/papers/q-2021-06-29-483/)"
] ]
} }
], ],
......
...@@ -445,7 +445,7 @@ ...@@ -445,7 +445,7 @@
"\n", "\n",
"## 参考文献\n", "## 参考文献\n",
"\n", "\n",
"[1] Li, Guangxi, et al. \"VSQL: Variational Shadow Quantum Learning for Classification.\" [arXiv:2012.08288 (2020).](https://arxiv.org/abs/2012.08288)\n", "[1] Li, Guangxi, Zhixin Song, and Xin Wang. \"VSQL: Variational Shadow Quantum Learning for Classification.\" [Proceedings of the AAAI Conference on Artificial Intelligence. Vol. 35. No. 9. 2021.](https://ojs.aaai.org/index.php/AAAI/article/view/17016)\n",
"\n", "\n",
"[2] Goodfellow, Ian, et al. Deep learning. Vol. 1. No. 2. Cambridge: MIT press, 2016.\n", "[2] Goodfellow, Ian, et al. Deep learning. Vol. 1. No. 2. Cambridge: MIT press, 2016.\n",
"\n", "\n",
......
...@@ -450,7 +450,7 @@ ...@@ -450,7 +450,7 @@
"\n", "\n",
"## References\n", "## References\n",
"\n", "\n",
"[1] Li, Guangxi, et al. \"VSQL: Variational Shadow Quantum Learning for Classification.\" [arXiv:2012.08288 (2020).](https://arxiv.org/abs/2012.08288)\n", "[1] Li, Guangxi, Zhixin Song, and Xin Wang. \"VSQL: Variational Shadow Quantum Learning for Classification.\" [Proceedings of the AAAI Conference on Artificial Intelligence. Vol. 35. No. 9. 2021.](https://ojs.aaai.org/index.php/AAAI/article/view/17016)\n",
"\n", "\n",
"[2] Goodfellow, Ian, et al. Deep learning. Vol. 1. No. 2. Cambridge: MIT press, 2016.\n", "[2] Goodfellow, Ian, et al. Deep learning. Vol. 1. No. 2. Cambridge: MIT press, 2016.\n",
"\n", "\n",
......
因为 它太大了无法显示 source diff 。你可以改为 查看blob
因为 它太大了无法显示 source diff 。你可以改为 查看blob
{
"cells": [
{
"cell_type": "markdown",
"source": [
"# 量子费舍信息\n",
"\n",
"<em> Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved. </em>"
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"## 概览\n",
"\n",
"本教程简要介绍经典费舍信息(classical Fisher information, CFI)和量子费舍信息(quantum Fisher information, QFI)的概念及其在量子机器学习中的应用,并展示如何调用量桨来计算它们。"
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"## 背景\n",
"\n",
"量子费舍信息这一概念源自量子传感领域,现已逐渐成为研究参数化量子系统的通用工具 [[1]](https://arxiv.org/abs/2103.15191),例如描述过参数化现象 [[2]](https://arxiv.org/abs/2102.01659),量子自然梯度下降 [[3]](https://arxiv.org/abs/1909.02108) 等。量子费舍信息是经典费舍信息在量子系统中的自然类比。经典费舍信息刻画了一个参数化的『概率分布』对其参数变化的灵敏度,而量子费舍信息刻画了一个参数化的『量子态』对其参数变化的灵敏度。\n",
"\n",
"按照传统的介绍方式,经典费舍信息会作为数理统计中参数估计的一部分内容出现,但对于初学者来说可能是复杂且不直观的。本教程将从几何的角度出发来介绍经典费舍信息,这不仅有助于直观理解,且更容易由此看出其与量子费舍信息之间的联系。"
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"### 经典费舍信息\n",
"\n",
"首先介绍经典费舍信息。对于一个参数化的概率分布 $p(\\boldsymbol{x};\\boldsymbol{\\theta})$,考虑如下问题\n",
"\n",
"- 一个轻微的参数改变会在多大程度上造成概率分布的改变?\n",
"\n",
"这是个关于微扰的问题,所以自然地想到做类似泰勒展开的操作。但在此之前,我们需要知道展开哪个函数,即我们需要量化『概率分布的改变』。更正式的说法是,我们需要定义任意两个概率分布之间的『距离』,记为 $d(p(\\boldsymbol{x};\\boldsymbol{\\theta}),p(\\boldsymbol{x};\\boldsymbol{\\theta}'))$,或简记为 $d(\\boldsymbol{\\theta},\\boldsymbol{\\theta}')$。\n",
"\n",
"一般地,一个合法的距离定义应该是非负的,当且仅当两点重合时为零,即\n",
"\n",
"$$\n",
"\\begin{aligned}\n",
"&d(\\boldsymbol{\\theta},\\boldsymbol{\\theta}')\\geq 0,\\\\\n",
"&d(\\boldsymbol{\\theta},\\boldsymbol{\\theta}')=0~\\Leftrightarrow~\\boldsymbol{\\theta}=\\boldsymbol{\\theta}'.\n",
"\\end{aligned}\n",
"\\tag{1}\n",
"$$\n",
"\n",
"考虑一个很短的距离函数的展开 $d(\\boldsymbol{\\theta},\\boldsymbol{\\theta}+\\boldsymbol{\\delta})$,以上条件会导致\n",
"\n",
"$$\n",
"\\begin{aligned}\n",
"&d(\\boldsymbol{\\theta},\\boldsymbol{\\theta})=0~\\Rightarrow~\\text{零阶项}=0,\\\\\n",
"&d(\\boldsymbol{\\theta},\\boldsymbol{\\theta}+\\boldsymbol{\\delta})\\geq 0~\\Rightarrow~\\boldsymbol{\\delta}=0~\\text{取极小值}\n",
"~\\Rightarrow~\\text{一阶项}=0.\n",
"\\end{aligned}\n",
"\\tag{2}\n",
"$$\n",
"\n",
"因此,在这个展开中最低阶的非零贡献来自二阶。因此它可被写为\n",
"\n",
"$$\n",
"\\begin{aligned}\n",
"d(\\boldsymbol{\\theta},\\boldsymbol{\\theta}+\\boldsymbol{\\delta})\n",
"=\\frac{1}{2}\\sum_{ij}\\delta_iM_{ij}\\delta_j+O(\\|\\boldsymbol{\\delta}\\|^3) \n",
"=\\frac{1}{2} \\boldsymbol{\\delta}^T M \\boldsymbol{\\delta} + O(\\|\\boldsymbol{\\delta}\\|^3),\n",
"\\end{aligned}\n",
"\\tag{3}\n",
"$$\n",
"\n",
"此处\n",
"\n",
"$$\n",
"M_{ij}(\\boldsymbol{\\theta})=\\left.\\frac{\\partial^2}{\\partial\\delta_i\\partial\\delta_j}d(\\boldsymbol{\\theta},\\boldsymbol{\\theta}+\\boldsymbol{\\delta})\\right|_{\\boldsymbol{\\delta}=0},\n",
"\\tag{4}\n",
"$$\n",
"\n",
"正是这个距离函数展开的海森矩阵。在微分几何的框架下,这称作流形的[度规](http://en.wikipedia.org/wiki/Metric_tensor)。以上简单的推导说明,我们总是可以用参数的一个二次型来近似表示一小段距离(如图1)。而二次型的系数矩阵,除了有一个 $1/2$ 因子的差别外,正是距离函数展开的海森矩阵。\n",
"\n",
"![feature map](./figures/FIM-fig-Sphere-metric.png \"Figure 1. Approximate a small distance on the 2-sphere as a quadratic form\")\n",
"<div style=\"text-align:center\">图 1. 将一小段距离近似为二次型,此处以二维球面为例绘制 </div>\n",
"\n",
"如果我们定义概率分布之间的距离为相对熵或称 KL 散度\n",
"\n",
"$$\n",
"d_{\\mathrm{KL}}(\\boldsymbol{\\theta}, \\boldsymbol{\\theta}^{\\prime})=\\sum_{\\boldsymbol{x}} p(\\boldsymbol{x};\\boldsymbol{\\theta}) \\log \\frac{p(\\boldsymbol{x};\\boldsymbol{\\theta})}{p(\\boldsymbol{x};\\boldsymbol{\\theta}^{\\prime})}.\n",
"\\tag{5}\n",
"$$\n",
"\n",
"对应的海森矩阵为\n",
"\n",
"$$\n",
"\\begin{aligned}\n",
"\\mathcal{I}_{ij}(\\boldsymbol{\\theta})&= \\left.\\frac{\\partial^2}{\\partial\\delta_i\\partial\\delta_j}d_{\\mathrm{KL}}(\\boldsymbol{\\theta},\\boldsymbol{\\theta}+\\boldsymbol{\\delta})\\right|_{\\boldsymbol{\\delta}=0}\\\\\n",
"&=-\\sum_{\\boldsymbol{x}} p(\\boldsymbol{x};\\boldsymbol{\\theta}) \\partial_{i} \\partial_{j} \\log p(\\boldsymbol{x};\\boldsymbol{\\theta})\n",
"=\\mathbb{E}_{\\boldsymbol{x}}[-\\partial_{i} \\partial_{j} \\log p(\\boldsymbol{x};\\boldsymbol{\\theta})] \\\\\n",
"&=\\sum_{\\boldsymbol{x}} \\frac{1}{p(\\boldsymbol{x};\\boldsymbol{\\theta})} \\partial_i p(\\boldsymbol{x};\\boldsymbol{\\theta}) \\cdot \\partial_j p(\\boldsymbol{x};\\boldsymbol{\\theta})\n",
"=\\mathbb{E}_{\\boldsymbol{x}}[\\partial_i\\log p(\\boldsymbol{x};\\boldsymbol{\\theta})\\cdot \\partial_j \\log p(\\boldsymbol{x};\\boldsymbol{\\theta})].\n",
"\\end{aligned}\n",
"\\tag{6}\n",
"$$\n",
"\n",
"这就是所谓的经典费舍信息矩阵(classical Fisher information matrix, CFIM),矩阵元越大说明概率分布对相应的参数变化越灵敏。上式中我们使用了偏导数符号的简记 $\\partial_i=\\partial/\\partial \\theta_i$。\n",
"\n",
"为什么 $\\mathcal{I}(\\boldsymbol{\\theta})$ 称为『信息』?这是因为,CFIM 刻画了概率分布在对应参数一个领域内的灵敏度,或称锐度。对参数变化越灵敏,说明我们越容易将其同其它概率分布区分开来,进一步地,说明我们需要越少的样本就可以完成这种区分,那么每个样本中平均所含的信息量就越多。\n",
"\n",
"参数化量子电路(parameterized quantum circuit, PQC)的测量结果会形成一个概率分布,因此可以对不同的测量基定义不同的 CFIM。目前在 NISQ 设备上计算 CFIM 的主要挑战是,可能出现的测量结果的数量会随着量子比特数的增加而指数地增加,这意味着可能有很多小概率的测量结果从未出现过,导致 CFIM 的计算出现发散。一些可能的解决方案包括直接忽略小的概率事件,以及贝叶斯更新等 [[1]](https://arxiv.org/abs/2103.15191)。"
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"### 量子费舍信息\n",
"\n",
"量子费舍信息是经典费舍信息的自然类比,只是距离函数不再定义在两个概率分布之间,而是定义在两个量子态之间。我们通常选用保真度距离\n",
"\n",
"$$\n",
"d_f(\\boldsymbol{\\theta},\\boldsymbol{\\theta}')=2-2|\\langle\\psi(\\boldsymbol{\\theta})|\\psi(\\boldsymbol{\\theta}')\\rangle|^2.\n",
"\\tag{7}\n",
"$$\n",
"\n",
"此处因子 $2$ 是人为乘上去的,为的是让后续的结果与 CFIM 对应上。一个参数化量子纯态 $|\\psi(\\boldsymbol{\\theta})\\rangle, \\boldsymbol{\\theta}\\in\\mathbb{R}^m$ 的量子费舍信息矩阵(quantum Fisher information matrix, QFIM)就是保真度距离展开的海森矩阵,即\n",
"\n",
"$$\n",
"\\begin{aligned}\n",
"\\mathcal{F}_{ij}(\\boldsymbol{\\theta})\n",
"&= \\left.\\frac{\\partial^2}{\\partial\\delta_i\\partial\\delta_j}d_{f}(\\boldsymbol{\\theta},\\boldsymbol{\\theta}+\\boldsymbol{\\delta})\\right|_{\\boldsymbol{\\delta}=0} \\\\\n",
"&=4 \\operatorname{Re}\\left[\\left\\langle\\partial_{i} \\psi \\mid \\partial_{j} \\psi\\right\\rangle - \\left\\langle\\partial_{i} \\psi \\mid \\psi\\right\\rangle\\left\\langle\\psi \\mid \\partial_{j} \\psi\\right\\rangle\\right],\n",
"\\end{aligned}\n",
"\\tag{8}\n",
"$$\n",
"\n",
"上式中简洁起见我们略写了自变量 $\\boldsymbol{\\theta}$。与 CFIM 类似,QFIM 刻画了参数化量子态对参数微小变化的灵敏度。此外值得一提的是,QFIM 可以被视为另一个被称作量子几何张量的复数矩阵的实部,或称为 Fubini-Study 度规 [[1]](https://arxiv.org/abs/2103.15191)。\n",
"\n",
"目前,人们已经提出了一些在 NISQ 设备上计算纯态 QFIM 的方法,其中最直接的两个方法是\n",
"\n",
"- 利用二阶参数平移规则计算每个矩阵元 [[4]](https://arxiv.org/abs/2008.06517)\n",
"$$\n",
"\\begin{aligned}\n",
"\\mathcal{F}_{i j}=-\\frac{1}{2} \\Big(&|\\langle\\psi(\\boldsymbol{\\theta}) \\mid \\psi(\\boldsymbol{\\theta}+(\\boldsymbol{e}_{i}+\\boldsymbol{e}_{j}) \\frac{\\pi}{2})\\rangle|^{2}\n",
"-|\\langle\\psi(\\boldsymbol{\\theta}) \\mid \\psi(\\boldsymbol{\\theta}+(\\boldsymbol{e}_{i}-\\boldsymbol{e}_{j}) \\frac{\\pi}{2})\\rangle|^{2}\\\\\n",
"-&|\\langle\\psi(\\boldsymbol{\\theta}) \\mid \\psi(\\boldsymbol{\\theta}-(\\boldsymbol{e}_{i}-\\boldsymbol{e}_{j}) \\frac{\\pi}{2})\\rangle|^{2}\n",
"+|\\langle\\psi(\\boldsymbol{\\theta}) \\mid \\psi(\\boldsymbol{\\theta}-(\\boldsymbol{e}_{i}+\\boldsymbol{e}_{j}) \\frac{\\pi}{2})\\rangle|^{2}\\Big),\n",
"\\end{aligned}\n",
"\\tag{9}\n",
"$$\n",
"其中 $\\boldsymbol{e}_{i}$ 是 $\\theta_i$ 对应方向的单位向量。\n",
"\n",
"- 利用有限差分计算 QFIM 沿一个确定方向的投影 [[1]](https://arxiv.org/abs/2103.15191)\n",
"$$\n",
"\\boldsymbol{v}^{T} \\mathcal{F} \\boldsymbol{v} \\approx \\frac{4 d_{f}(\\boldsymbol{\\theta}, \\boldsymbol{\\theta}+\\epsilon \\boldsymbol{v})}{\\epsilon^{2}}.\n",
"\\tag{10}\n",
"$$\n",
"这个量可以被视为著名的 Fisher-Rao 模在量子态空间的类比。\n",
"\n",
"对于混态,QFIM 可以类似地通过 Bures 保真度距离的展开来定义\n",
"\n",
"$$\n",
"d_B(\\boldsymbol{\\theta},\\boldsymbol{\\theta}')\\equiv \n",
"2-2\\left[\\text{Tr}\\left([\\sqrt{\\rho(\\boldsymbol{\\theta})} \\rho(\\boldsymbol{\\theta}')\\sqrt{\\rho(\\boldsymbol{\\theta})}]^{1/2}\\right)\\right]^2,\n",
"\\tag{11}\n",
"$$\n",
"\n",
"或者等价地($\\log x\\sim x-1$),通过如下形式的 $\\alpha=1/2$ 的 Rényi 相对熵的展开来定义 [[5]](https://arxiv.org/abs/1308.5961)\n",
"\n",
"$$\n",
"\\begin{aligned}\n",
"d_R(\\boldsymbol{\\theta},\\boldsymbol{\\theta}') &\\equiv 2\\widetilde{D}_{\\alpha=1/2}(\\rho(\\boldsymbol{\\theta'}) \\| \\rho(\\boldsymbol{\\theta})), \\\\\n",
"\\widetilde{D}_{\\alpha}(\\rho \\| \\sigma) \n",
"&\\equiv \n",
"\\frac{1}{\\alpha-1} \\log \\operatorname{Tr}\\left[\\left(\\sigma^{\\frac{1-\\alpha}{2 \\alpha}} \\rho \\sigma^{\\frac{1-\\alpha}{2 \\alpha}}\\right)^{\\alpha}\\right].\\\\\n",
"\\end{aligned}\n",
"\\tag{12}\n",
"$$\n",
"\n",
"更多细节请参考这篇综述 [[1]](https://arxiv.org/abs/2103.15191) 。"
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"### 经典与量子费舍信息的关系\n",
"\n",
"根据定义,对于一个参数化的量子电路,CFIM 依赖于测量基,而 QFIM 不依赖。事实上可以证明,一个量子态 $\\rho(\\boldsymbol{\\theta})$ 的 QFIM 是其在任意测量基下对应 CFIM 的一个上限,即\n",
"\n",
"$$\n",
"\\mathcal{I}[\\mathcal{E}[\\rho(\\boldsymbol{\\theta})]]\\leq \\mathcal{F}[\\rho(\\boldsymbol{\\theta})],~\\forall\\mathcal{E},\n",
"\\tag{13}\n",
"$$\n",
"\n",
"此处 $\\mathcal{E}$ 表示测量对应的量子操作。正定矩阵间不等式的含义是,大的减去小的结果仍然是一个正定矩阵。由于对量子态的测量永远无法提取出比量子态本身更多的信息,因此上式的成立是很自然的。数学上这根源于保真度距离对于保迹量子操作的单调性 [[1]](https://arxiv.org/abs/2103.15191)。"
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"### 应用:有效维数\n",
"\n",
"经典/量子费舍信息矩阵的秩在参数空间的最大值可以用来衡量神经网络表达能力,称为经典/量子有效维数\n",
"\n",
"$$\n",
"d_{\\text{eff}}=\\underset{\\boldsymbol{\\theta}\\in\\Theta} {\\max}\n",
"\\operatorname{rank}{\\mathcal{F}}(\\boldsymbol{\\theta}).\n",
"\\tag{14}\n",
"$$\n",
"\n",
"秩的大小刻画了参数变化会造成概率分布/量子态变化的方向的数量。非满秩意味着有一些特定方向的参数变化不能实际地导致概率分布/量子态发生变化,或者说有一些参数自由度是冗余的,可以把它们从模型中投影掉,因此这种现象被称作过参数化。另一方面,有效维数越大,对应着更多可以延伸的方向,这意味着模型对应的函数空间更大,即表达能力更强。\n",
"\n",
"在机器学习的语境下,『经验费舍信息矩阵』[[6]](https://arxiv.org/abs/2011.00027) 的使用更为广泛,它与 CFIM 的区别是用对样本的求和代替了求期望\n",
"\n",
"$$\n",
"\\tilde{\\mathcal{I}}_{ij}(\\boldsymbol{\\theta})\n",
"=\\frac{1}{n}\\sum_{k=1}^{n}\n",
"\\partial_i\\log p(x_k,y_k;\\boldsymbol{\\theta})\n",
"\\partial_j\\log p(x_k,y_k;\\boldsymbol{\\theta}),\n",
"\\tag{15}\n",
"$$\n",
"\n",
"此处 $(x_k,y_k)^{n}_{k=1}$ 是独立同分布的样本,分布为 $p(x,y;\\boldsymbol{\\theta})=p(y|x;\\boldsymbol{\\theta})p(x)$。显然,经验费舍信息矩阵在无限样本的极限下可以回到 CFIM,只要满足(1)模型被训练到全局最优;(2)模型拥有足够的表达能力来表达底层的数据分布。使用经验费舍信息矩阵的优势在于,它可以利用现成的样本直接计算,而不是为了计算公式中的积分而生成新的样本。\n",
"\n",
"利用经验费舍信息矩阵,我们可以定义有效维数的一个变体 \n",
"\n",
"$$\n",
"d_{\\text{eff}}(\\gamma, n)=\n",
"2 \\frac{\\log \\left(\\frac{1}{V_{\\Theta}} \\int_{\\Theta} \\sqrt{\\operatorname{det}\\left( 1 + \\frac{\\gamma n}{2 \\pi \\log n} \\hat{\\mathcal{I}}( \\boldsymbol{\\theta})\\right)} \\mathrm{d} \\boldsymbol{\\theta} \\right)}\n",
"{\\log \\left(\\frac{\\gamma n}{2 \\pi \\log n}\\right)},\n",
"\\tag{16}\n",
"$$\n",
"\n",
"其中 $V_{\\Theta}:=\\int_{\\Theta} \\mathrm{d} \\boldsymbol{\\theta} \\in \\mathbb{R}_{+}$ 是参数空间的体积。$\\gamma\\in(0,1]$ 是一个人为可调参数。$\\hat{\\mathcal{I}} (\\boldsymbol{\\theta}) \\in \\mathbb{R}^{d\\times d}$ 是归一化的经验费舍信息矩阵\n",
"\n",
"$$\n",
"\\hat{\\mathcal{I}}_{i j}(\\boldsymbol{\\theta}):= \\frac{V_{\\Theta} d }{\\int_{\\Theta} \\operatorname{Tr}(F( \\boldsymbol{\\theta} ) \\mathrm{d} \\theta} \\tilde{\\mathcal{I}}_{i j}(\\boldsymbol{\\theta}).\n",
"\\tag{17}\n",
"$$\n",
"\n",
"这个定义乍看起来可能很迷惑,因为它比上文通过秩来定义要复杂得多。然而,它实际上可以在无限样本的极限下 $n\\rightarrow \\infty$ 回到 CFIM 最大秩的定义 [[6]](https://arxiv.org/abs/2011.00027)。若忽略定义中的一些系数和取对数的操作,此处定义的有效维数可以粗略地看作归一化 CFIM 加上一个单位矩阵的本征谱的几何平均。依据几何平均与算术平均间的不等式关系,可知本征谱分布越均匀,有效维数越大。这和我们的直觉是一致的。在这个意义上,它可以看作是一个软化版本的有效维数。\n",
"\n",
"另外,费舍信息不仅可以用来计算模型的表达能力,还可以用来表征模型的可训练性。如果费舍信息矩阵的矩阵元在参数空间的平均随体系规模的增大而指数地趋于零,即概率分布/量子态对参数变化的灵敏度指数地趋于零,那么我们将无法高效地区分它们,也就意味着贫瘠高原现象的存在 [[6]](https://arxiv.org/abs/2011.00027)。"
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"## 调用量桨计算费舍信息"
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"### 计算量子费舍信息\n",
"\n",
"利用量桨工具,通过以下步骤我们就可以方便地算出 QFIM。\n",
"\n",
"1. 调用 `UAnsatz` 类定义一个量子电路。\n",
"2. 调用 `QuantumFisher` 类定义一个 QFIM 计算器。\n",
"3. 调用 `get_qfisher_matrix()` 方法计算 QFIM。\n",
"\n",
"其中计算器 `QuantumFisher` 会追踪量子电路 `UAnsatz` 的实时变化。\n",
"\n",
"现在来着手写代码。首先导入一些必要的包。"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 1,
"source": [
"import paddle\n",
"from paddle_quantum.circuit import UAnsatz\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from paddle_quantum.utils import QuantumFisher, ClassicalFisher\n",
"import warnings\n",
"warnings.filterwarnings(\"ignore\")"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"然后定义量子电路。作为一个简单的例子,我们采用布洛赫角表示的单个量子比特\n",
"\n",
"$$\n",
"|\\psi(\\theta,\\phi)\\rangle=R_z(\\phi)R_y(\\theta)|0\\rangle=e^{-i\\phi/2}\\cos\\frac{\\theta}{2}|0\\rangle+e^{i\\phi/2}\\sin\\frac{\\theta}{2}|1\\rangle.\n",
"\\tag{18}\n",
"$$\n",
"\n",
"利用 (8) 式可以计算出对应 QFIM 的解析表达式为\n",
"\n",
"$$\n",
"\\mathcal{F}(\\theta,\\phi)=\\left(\\begin{matrix}\n",
"1&0\\\\\n",
"0&\\sin^2\\theta\n",
"\\end{matrix}\\right).\n",
"\\tag{19}\n",
"$$"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 2,
"source": [
"def circuit_bloch():\n",
" cir = UAnsatz(1)\n",
" theta = 2 * np.pi * np.random.random(2)\n",
" theta = paddle.to_tensor(theta, stop_gradient=False, dtype='float64')\n",
" cir.ry(theta[0], which_qubit=0)\n",
" cir.rz(theta[1], which_qubit=0)\n",
" \n",
" return cir"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 3,
"source": [
"cir = circuit_bloch()\n",
"print(cir)"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"--Ry(1.888)----Rz(2.181)--\n",
" \n"
]
}
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"定义 QFIM 计算器然后计算不同 $\\theta$ 对应的 QFIM 矩阵元 $\\mathcal{F}_{\\phi\\phi}$ 。"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 4,
"source": [
"qf = QuantumFisher(cir)\n",
"# 记录 QFIM 的矩阵元 F_{phi,phi}\n",
"list_qfisher_elements = []\n",
"num_thetas = 21\n",
"thetas = np.linspace(0, np.pi, num_thetas)\n",
"for theta in thetas:\n",
" list_param = cir.get_param().tolist()\n",
" list_param[0] = theta\n",
" cir.update_param(list_param)\n",
" # 计算 QFIM\n",
" qfim = qf.get_qfisher_matrix()\n",
" print(f'The QFIM at {np.array(list_param)} is \\n {qfim.round(14)}.')\n",
" list_qfisher_elements.append(qfim[1][1])"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"The QFIM at [0. 2.18107874] is \n",
" [[1. 0.]\n",
" [0. 0.]].\n",
"The QFIM at [0.15707963 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.02447174]].\n",
"The QFIM at [0.31415927 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.0954915]].\n",
"The QFIM at [0.4712389 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.20610737]].\n",
"The QFIM at [0.62831853 2.18107874] is \n",
" [[ 1. -0. ]\n",
" [-0. 0.3454915]].\n",
"The QFIM at [0.78539816 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.5]].\n",
"The QFIM at [0.9424778 2.18107874] is \n",
" [[ 1. -0. ]\n",
" [-0. 0.6545085]].\n",
"The QFIM at [1.09955743 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.79389263]].\n",
"The QFIM at [1.25663706 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.9045085]].\n",
"The QFIM at [1.41371669 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.97552826]].\n",
"The QFIM at [1.57079633 2.18107874] is \n",
" [[1. 0.]\n",
" [0. 1.]].\n",
"The QFIM at [1.72787596 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.97552826]].\n",
"The QFIM at [1.88495559 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.9045085]].\n",
"The QFIM at [2.04203522 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.79389263]].\n",
"The QFIM at [2.19911486 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.6545085]].\n",
"The QFIM at [2.35619449 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.5]].\n",
"The QFIM at [2.51327412 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.3454915]].\n",
"The QFIM at [2.67035376 2.18107874] is \n",
" [[ 1. -0. ]\n",
" [-0. 0.20610737]].\n",
"The QFIM at [2.82743339 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.0954915]].\n",
"The QFIM at [2.98451302 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.02447174]].\n",
"The QFIM at [3.14159265 2.18107874] is \n",
" [[1. 0.]\n",
" [0. 0.]].\n"
]
}
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"画出 $\\mathcal{F}_{\\phi\\phi}$ 随 $\\theta$ 变化的图像。"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 5,
"source": [
"# 创建图像\n",
"fig = plt.figure(figsize=(9, 6))\n",
"ax = fig.add_subplot(111)\n",
"# 绘制 QFIM\n",
"ax.plot(thetas, list_qfisher_elements, 's', markersize=11, markerfacecolor='none')\n",
"# 绘制 sin^2 theta\n",
"ax.plot(thetas, np.sin(thetas) ** 2, linestyle=(0, (5, 3)))\n",
"# 设置图例,标签,刻度\n",
"label_font_size = 18\n",
"ax.legend(['get_qfisher_matrix()[1][1]', '$\\\\sin^2\\\\theta$'], \n",
" prop= {'size': label_font_size}, frameon=False) \n",
"ax.set_xlabel('$\\\\theta$', fontsize=label_font_size)\n",
"ax.set_ylabel('QFIM element $\\\\mathcal{F}_{\\\\phi\\\\phi}$', fontsize=label_font_size)\n",
"ax.tick_params(labelsize=label_font_size)"
],
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 648x432 with 1 Axes>"
],
"image/png": "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4NSJGsU6kpxzepTw6NSpk5Ny2LHN7wRhaXHtu1HZtqKuueYaB7gXXngh6PIePXrsWrZq1SpXvXp1N2jQoGLHufzyy11KSopbunTprmUtWrQotH84du7c6Zo1a+YaNGjgsrOzdy1fv369a968uQPchAkTdi1ftmyZA9zo0aOLHQtwZ5111q7/jxgxwgFu9erVpWY466yzHOAuvvjiQstfeeUVB7jHH39817I33njDAe6JJ54otO2OHTtcp06dXFZWlsvLyyuUtUqVKm7RokVlnYqgRo8e7QDXv3//Xcd1zrkHHnjAAa5OnTpuxYoVu5avWbPGVa9e3Z1++umFjrNp06Zix160aJGrVq1asZ+7tN9nixYtHOCefPLJYutmzJhR7PflnHNz5851VatWdf3793e5ubnuqKOOctWqVXNfffVVoe2GDBniALdhw4ag39s5584991wHuLVr1+5a1qNHD9eiRYsS98mXnZ1d7DlSkqLbTZgwwQFuxowZZe7br18/570dli7/eee7T8c5N7qucwtf8jtJ3AHmuxLe8+OsvVDiQpVqfidICO+88w5NmjRh0KBBhZYX7ZgM8Nprr7Ft2zbOPfdc1q5dW+gxYMAA8vLymDZtWkRyffXVV/z222+cffbZZGRk7Fper149Lrroogodu149rwP+66+/zs6dO8vcfsSIEYX+n9/59eeff9617IUXXqBOnTocf/zxhc7L+vXrGTBgAMuXLy+0PUC/fv1KbMUK1eWXX17ozqX8O5QGDhxIs2bNdi1v2LAhbdq0KZahVq1agPeh9Z9//tnVn6ZNmzZBLwuWpn79+px99tkhb3/wwQdz++238+6779K9e3emTZvGmDFj6NixY6HtsrOzqVKlSqktaPl3nq1ZsyaszFKKQ4fBIZdCi0P9TpJQdMlMKs45NdtGwbJly+jSpUuxfg6NGjUiPT290LLFixcDcNRRR5V4vNWrV0ck1y+//AJA27Zti61r3759hY49bNgw3nrrLS655BKuvfZaDj/8cPr27cugQYOCXtJr2bJlof/nv/kWHA9n8eLFbNy4kd13L3namNWrVxe6HFf00lx5FM222267AbDnnnsW23a33Xbj119/LbRs4cKF3HTTTcycObPYJdJgxyhNq1atwr6b75prruHdd99l9uzZ9O7dm+HDhxfbJpQxeVxgvkyNGxVBKanQ906/UyQcFURScXMegL+WQr/7NIu9T/LfdJ5//nmaNGkSdJuib9CxqEGDBsybN4/Zs2czdepUPvnkE0aMGMHo0aN5//33OfTQwp+IS3qTzz8f+f9u2LAhL730Uonfd9999y30/7S0tAr8FKVnCyXzihUr6N69O3Xr1uWmm26iTZs21KpVCzNj+PDhpfYBCqY8P8/y5ct3deBesmQJmzZtKnanXcOGDdm5cycbNmzY1bpX1F9//bVrW5FYpoJIKubP72D67dD2WEjR0ymSsrKyWLJkCXl5eYVaidasWcP69esLbZvfwTYjI6PUVqJ8Ffm0nl9Y/fDDD8XWLVq0qNzHzZeamkrPnj133UX37bff0qlTJ26//fZinbZDsffee/PTTz9xyCGHULt27QrnqwyTJ09m06ZNvP322/Tq1avQunXr1lG9euEbFiLd+rJz504GDRrEzp07efDBB7niiiu4+OKLi432nF9I/vzzz3TuHHQCcZYsWULjxo0LDdooEbZzG2xaA+nNyt5WSqQ+RFJ+O7bC6+dDWgPoP06XzSJswIAB/PHHH7z88suFlt97773Ftj311FOpXr06o0ePJien+CCTGzZsYNu2bbv+X7t27V2f3MPVqVMn9thjDyZMmMDatWt3Lf/nn3+K3eIfroLHy9e2bVtq1qxZ7rxDhgwhLy+P6667Luj6SF1KjKT8VqSCrUYATz75JH/++Wex7Svy+wzmxhtv5IsvvuDhhx/msssu46qrruLFF1/kueeeK7RdftE6d+7coMfJzc1l/vz59OjRI2LZJIj/+xe8dKr3mizlpo/0Un7Tb4PsxfCv1yGt+KB7UjHXXnstL730EmeffTZffvklbdu2Zfbs2Xz22WdkZGQUahXYY489eOyxxzjvvPNo164dgwcPpkWLFmRnZ/Pdd9/x5ptvsmjRIrKysgA45JBDePrpp7npppto164dKSkpDBgwYFdH3tKkpqZy//33c+qpp9KlSxfOP/98qlSpwjPPPEODBg1YsWJFuX/m888/n99//53evXvTokULcnJymDRpEhs3biw0/k048m+1f/jhh1mwYAH9+/cnIyOD33//nc8//5wlS5bs6hcVK4455hjS0tIYPHgww4YNY7fddmPOnDm8//77tGrVqliH84r8PouaOnUqd999N2ecccauMaLuvPNOZs2axbBhwzjssMN2tUh26tSJli1b8v777xcbqRq82/I3b97MKaecElaG22+/HYAtW7YAXith/rLu3bvTvXv3sH+uot555x2++eYbwGvFKvh909PTg/48MevgC+HFk73X5D53+J0mbqkgkvL5ZZY3YupB58HeZV+iiWWZ6TVDHoE6M71mlNP8T0ZGBp9++ilXXXUVzzzzDGa2azDBgw46iJo1C2c5++yzad26Nffeey9PPPEE69evJyMjgzZt2nDbbbfRuHHjXdvecccd/PXXXzzyyCOsX78e5xzLli0L+Q305JNP5rXXXuPf//43t9xyC40aNWLo0KF0796d3r17l/tnHjx4MM8++yzPPfcc2dnZ1K1bl/bt2/Paa6+FPNJxMM888wy9evVi/Pjx3HXXXWzfvp3GjRvTsWNH7rrrrnIfN1patWrFBx98wPXXX8+dd95JamoqXbt23VWUFB1Es6K/z3xr1qxhyJAhtGzZslBrX9WqVXn55Zfp0KEDgwYN4rPPPqNatWqYGRdeeCHXX389q1evLtZxfeLEiTRu3JjjjjsurBw33VR4UNeFCxeycOFCAEaPHh2Rguj1118v1uKV/31btGgRXwXR3kdD53Ph80egdR/Ys+LnJymVdD++HhqHqERb/nZubHvnHuzo3LbNfqdJOmvXrnWAu/DCC/2OUkxJ49pI4tqwYYNr1KiRu+GGGwot/+OPP1zNmjXdAw88UGyfHj16uGbNmrns7OxC4xOFKy8vz2VnZwcdryh/HKI333zTZWdnu61bt5b7+2zYsMFlZ2e7008/PTbGIQpm2ybnHujgvTbnrPc7TcyilHGI1EIkQZU24WlD/mZs1d24d+epfHvzjISZ8DQW5eTkFGsJGjNmDOBNWinit7p163LrrbcycuTIQjPejxkzhj322IOLL7446H6//fYbDRs2JDU1NaQxp4JZvXp1iXdV5jv++OMBr7Uq2GSyoTj11FOZMmVKufatNNVqcd6mC3h823W8fccZXLnjklI31+t2cSqIJKiyJzw9k/xGWU14Gj3HHnssLVq0oGPHjuTl5fHxxx/z7rvvcthhh+16oY+UDRs2BO2QXVC1atWCTtKa6HJyctiwYUOZ2xW8LJlMLrroomKDco4bN45x48YF3X7s2LH8/fffABWaT6x+/fpMnTp11/+bNm266999+vQptK7o0ArhGDNmTNABUWPNtH+aUaXvtZw48y5OHHy5d/msBHrdLk4FkUgM69+/P88//zyTJ08mJyeHPfbYg6uuuorRo0eHPdBeWa644opifSqK6tGjR7FJP5PBpEmTQhrp2RW5K0yC69SpU0SOU61atRKHmWjSpEmZrUehOvDAAyNynErR7Srvzt+WvcreVgpRQSShycuD3O1QtYbfSZLKVVddxVVXXVUp32vkyJFlXlLIH225JD179kzIoqBoa4NIzEqtCl3O9ztFXFJBJGXLy4OPboSl02Hou1Aro+x9JO60b9++wlNvJKpItjaISGzSwIxSutyd8NalMPcR71bONI02KyISN7J/gg9Gea/lUioVRFKyHTnwymD45iXoeT0c8x+NRi0iEk+WTocvHoNXhmgk6zKoIJKg6rAFXjgZfvwAjr0Xel6rYkhEJN4ccpH3Gv7j+/DCSbC17Lslk5UKIiku529ernY7/DYXTnpKHfREROJZl/O91/Lf5sKz/WFTtt+JYpIKIimuWh1+dpkw6P9gv5P9TiMiIhW138nea/ran+GZPmSioqgoFURSXGoVRuy41JsfR0REEsPeR8OQt2DLWgakfu53mpij2+7Fk5cHBUaMjdUJTyWytm3bxrBhw/j444/Jzs6mSZMmXHbZZVx22WV+RxORMIX6ut2E20mpl8moSsgUT1QQCSz5GKbeDGe+AXW82ao1x01y2LlzJ40bN+ajjz6iZcuWfPvtt/Tp04fdd9+dU0891e94IhIGvW5XjC6ZJbvv34CXTgN0B1m8mjlzJmbGs88+G/a+tWrV4rbbbmOvvfYiJSWFAw88kIEDB/Lpp5+WuM+UKVPo2bMntWvXpmHDhgwbNoytW3U7r0jc+uNb+O+bfqfwnQqiZDbvaXjtHNijszcCdaB1SJLXjh07mD17Nvvvv3/Q9WPHjqVv3740adKE+++/nwEDBvDII49wxRVXVHJSEYmYT+6BV4fC/Gf8TuIrS8R5hyKlc+fObv78+X7HiDznYPa9MP122LsPnPIsVEvzO5WUU15eHtu3b6dq1aoVnvD1wgsvZMGCBcyZM4dq1aoVWjdt2jR69+7N3XffXWjm7759+zJjxgyys7OpW7duhb6/iPhg+xavIPp5ChxxkzdBbIKOO2dmXznnOgdbpxaiZJOXB1Nu8Iqh/U+D019UMRTnUlJSqFGjRoWLoSuvvJLPP/+cDz74oFgxlJeXxxVXXEGHDh2KTTbbs2dPtm/fzvfff1+h7y8iPqmW5r0X7H8aTL/Ne4/Iy/M7VaVTQZSMtqyDgy+G4x/3ZkaWmLV161ZuueUW2rRpQ1paGunp6ey3335cc801u7YJ1ofo2WefxcyYPn069957L61ataJ69eq0bt2a5557rtj3GT58OFOnTuXjjz8mI6P45L1Tpkxh0aJFXH755ViRT475xdOGDRoBVyRupVb13hMOvtibu/KtSyB3h9+pKpXuMks2KSlw/KNgKQnbJJpILr30Up555hmGDBnClVdeyc6dO/n555+ZPn16SPtff/315OTkcOGFF1K9enUee+wxhg4dyl577UXXrl0BuPzyy5k+fTozZsygYcOGQY8zadIkUlNT6datG2vXri20bvXq1QDUqVOnAj+piPguJQX63gVp9WHGHdC6D+xzgt+pKo0KomSUUrFLK1J5Jk+ezDHHHBO0VScU27ZtY968ebtacU4++WRatmzJww8/TNeuXfn111956KGHqF69Onvuueeu/bp168YHH3yw6/8zZswgNzeXVq1alfi9WrZsWa6MIhJDzKDHSNizBzTr4neaSqWCKNFtWgNvXwbH3gPpzf1OE30T+pW87sAzoMO/Knf7CqpXrx7//e9/+f7779l3333D3v+SSy4p1B8oMzOT1q1b8/PPPwPQokULyrqxYu3ataxYsYITTjiBSy65pNj6U089lerVq9O0adOw84lIjGp+sN8JKp0KojjXdcx0Vq7PCbpuD8tmYtU72d3Wc+73/8eKup01cFecGTduHIMHD2a//fajZcuW9OrViwEDBjBgwABSUsruAhis1aZBgwb8+uuvIWf45ZdfADjooIM46qijCq1btmwZf//9N2eccUbIxxOR+NJ1zHQyNnzHOuryu2tU6raZ6TXj9n1GBVGcW7k+h+VjgrRarF4EL1wFO7bBv97j5WYHhTwVR1w7O8yfMdrbV9Bxxx3H8uXLef/995k1axbTpk3j6aefplu3bkybNq3Y3WBFlXTnWTjDbWzatAkI3kfotddeA+C0004L+XgiEl/+XL+JOU0mwM6t3owGu7cvcdt4fp/RXWaJ6LcvYcIx3r/P+RCaHeRvHqmQ+vXrc+aZZ/Lkk0/yyy+/MHLkSGbPns1bb71VKd8/f2yhf/75p9Dy7du389hjj9GmTRv69SvlUqKI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"
},
"metadata": {
"needs_background": "light"
}
}
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"可以看到程序输出和解析结果是一致的。\n",
"\n",
"此外,我们还可以调用 `get_qfisher_norm()` 方法来计算式 (10) 中的量子费舍信息矩阵在某个方向的投影。\n",
"\n",
"举一个和上面不同的例子,两个量子比特上的一个典型的 hardware-efficient 拟设\n",
"\n",
"$$\n",
"|\\psi(\\boldsymbol{\\theta})\\rangle=\\left[R_{y}\\left( \\theta_{3}\\right) \\otimes R_{y}\\left( \\theta_{4}\\right)\\right] \\text{CNOT}_{0,1}\\left[ R_{y}\\left( \\theta_{1}\\right) \\otimes R_{y}\\left( \\theta_{2}\\right)\\right]|00\\rangle.\n",
"\\tag{20}\n",
"$$\n",
"\n",
"对应的 QFIM 为\n",
"\n",
"$$\n",
"\\mathcal{F}(\\theta_1,\\theta_2,\\theta_3,\\theta_4)=\\left(\\begin{array}{cc|cc}\n",
"1 & 0 & \\sin \\theta_{2} & 0 \\\\\n",
"0 & 1 & 0 & \\cos \\theta_{1} \\\\\n",
"\\hline \n",
"\\sin \\theta_{2} & 0 & 1 & -\\sin\\theta_1\\cos\\theta_2 \\\\\n",
"0 & \\cos \\theta_{1} & -\\sin\\theta_1\\cos\\theta_2 & 1\n",
"\\end{array}\\right).\n",
"\\tag{21}\n",
"$$\n",
"\n",
"定义相应的量子电路。"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 6,
"source": [
"def circuit_hardeff_2qubit():\n",
" cir = UAnsatz(2)\n",
" theta = 2 * np.pi * np.random.random(4)\n",
" theta = paddle.to_tensor(theta, stop_gradient=False, dtype='float64')\n",
" cir.ry(theta[0], which_qubit=0)\n",
" cir.ry(theta[1], which_qubit=1)\n",
" cir.cnot(control=[0, 1])\n",
" cir.ry(theta[2], which_qubit=0)\n",
" cir.ry(theta[3], which_qubit=1)\n",
"\n",
" return cir"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 7,
"source": [
"cir = circuit_hardeff_2qubit()\n",
"print(cir)"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"--Ry(2.614)----*----Ry(3.253)--\n",
" | \n",
"--Ry(2.906)----x----Ry(5.027)--\n",
" \n"
]
}
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"定义 QFIM 计算器并计算不同 $\\theta$ 对应的 QFIM 在 $\\boldsymbol{v}=(1,1,1,1)$ 方向上的投影 $\\boldsymbol{v}^T\\mathcal{F}\\boldsymbol{v}$ (固定 $\\theta_1=\\theta_2=\\theta$)。"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 8,
"source": [
"qf = QuantumFisher(cir)\n",
"v = [1, 1, 1, 1]\n",
"# 记录 QFIM 投影\n",
"list_qfisher_norm = []\n",
"num_thetas = 41\n",
"thetas = np.linspace(0, np.pi * 4, num_thetas)\n",
"for theta in thetas:\n",
" list_param = cir.get_param().tolist()\n",
" list_param[0] = theta\n",
" list_param[1] = theta\n",
" cir.update_param(list_param)\n",
" # 计算 QFIM 投影\n",
" qfisher_norm = qf.get_qfisher_norm(v)\n",
" print(\n",
" f'The QFI norm along {v} at {np.array(list_param)} is {qfisher_norm:.8f}.'\n",
" )\n",
" list_qfisher_norm.append(qfisher_norm)"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"The QFI norm along [1, 1, 1, 1] at [0. 0. 3.2533421 5.02652273] is 5.99962501.\n",
"The QFI norm along [1, 1, 1, 1] at [0.31415927 0.31415927 3.2533421 5.02652273] is 5.93033916.\n",
"The QFI norm along [1, 1, 1, 1] at [0.62831853 0.62831853 3.2533421 5.02652273] is 5.84133590.\n",
"The QFI norm along [1, 1, 1, 1] at [0.9424778 0.9424778 3.2533421 5.02652273] is 5.84309143.\n",
"The QFI norm along [1, 1, 1, 1] at [1.25663706 1.25663706 3.2533421 5.02652273] is 5.93367838.\n",
"The QFI norm along [1, 1, 1, 1] at [1.57079633 1.57079633 3.2533421 5.02652273] is 5.99962501.\n",
"The QFI norm along [1, 1, 1, 1] at [1.88495559 1.88495559 3.2533421 5.02652273] is 5.86697827.\n",
"The QFI norm along [1, 1, 1, 1] at [2.19911486 2.19911486 3.2533421 5.02652273] is 5.38230779.\n",
"The QFI norm along [1, 1, 1, 1] at [2.51327412 2.51327412 3.2533421 5.02652273] is 4.49128513.\n",
"The QFI norm along [1, 1, 1, 1] at [2.82743339 2.82743339 3.2533421 5.02652273] is 3.28287364.\n",
"The QFI norm along [1, 1, 1, 1] at [3.14159265 3.14159265 3.2533421 5.02652273] is 1.97995933.\n",
"The QFI norm along [1, 1, 1, 1] at [3.45575192 3.45575192 3.2533421 5.02652273] is 0.87758767.\n",
"The QFI norm along [1, 1, 1, 1] at [3.76991118 3.76991118 3.2533421 5.02652273] is 0.25010151.\n",
"The QFI norm along [1, 1, 1, 1] at [4.08407045 4.08407045 3.2533421 5.02652273] is 0.26070618.\n",
"The QFI norm along [1, 1, 1, 1] at [4.39822972 4.39822972 3.2533421 5.02652273] is 0.90660775.\n",
"The QFI norm along [1, 1, 1, 1] at [4.71238898 4.71238898 3.2533421 5.02652273] is 2.01995733.\n",
"The QFI norm along [1, 1, 1, 1] at [5.02654825 5.02654825 3.2533421 5.02652273] is 3.32425271.\n",
"The QFI norm along [1, 1, 1, 1] at [5.34070751 5.34070751 3.2533421 5.02652273] is 4.52539873.\n",
"The QFI norm along [1, 1, 1, 1] at [5.65486678 5.65486678 3.2533421 5.02652273] is 5.40406149.\n",
"The QFI norm along [1, 1, 1, 1] at [5.96902604 5.96902604 3.2533421 5.02652273] is 5.87599852.\n",
"The QFI norm along [1, 1, 1, 1] at [6.28318531 6.28318531 3.2533421 5.02652273] is 5.99962501.\n",
"The QFI norm along [1, 1, 1, 1] at [6.59734457 6.59734457 3.2533421 5.02652273] is 5.93033916.\n",
"The QFI norm along [1, 1, 1, 1] at [6.91150384 6.91150384 3.2533421 5.02652273] is 5.84133590.\n",
"The QFI norm along [1, 1, 1, 1] at [7.2256631 7.2256631 3.2533421 5.02652273] is 5.84309143.\n",
"The QFI norm along [1, 1, 1, 1] at [7.53982237 7.53982237 3.2533421 5.02652273] is 5.93367838.\n",
"The QFI norm along [1, 1, 1, 1] at [7.85398163 7.85398163 3.2533421 5.02652273] is 5.99962501.\n",
"The QFI norm along [1, 1, 1, 1] at [8.1681409 8.1681409 3.2533421 5.02652273] is 5.86697827.\n",
"The QFI norm along [1, 1, 1, 1] at [8.48230016 8.48230016 3.2533421 5.02652273] is 5.38230779.\n",
"The QFI norm along [1, 1, 1, 1] at [8.79645943 8.79645943 3.2533421 5.02652273] is 4.49128513.\n",
"The QFI norm along [1, 1, 1, 1] at [9.1106187 9.1106187 3.2533421 5.02652273] is 3.28287364.\n",
"The QFI norm along [1, 1, 1, 1] at [9.42477796 9.42477796 3.2533421 5.02652273] is 1.97995933.\n",
"The QFI norm along [1, 1, 1, 1] at [9.73893723 9.73893723 3.2533421 5.02652273] is 0.87758767.\n",
"The QFI norm along [1, 1, 1, 1] at [10.05309649 10.05309649 3.2533421 5.02652273] is 0.25010151.\n",
"The QFI norm along [1, 1, 1, 1] at [10.36725576 10.36725576 3.2533421 5.02652273] is 0.26070618.\n",
"The QFI norm along [1, 1, 1, 1] at [10.68141502 10.68141502 3.2533421 5.02652273] is 0.90660775.\n",
"The QFI norm along [1, 1, 1, 1] at [10.99557429 10.99557429 3.2533421 5.02652273] is 2.01995733.\n",
"The QFI norm along [1, 1, 1, 1] at [11.30973355 11.30973355 3.2533421 5.02652273] is 3.32425271.\n",
"The QFI norm along [1, 1, 1, 1] at [11.62389282 11.62389282 3.2533421 5.02652273] is 4.52539873.\n",
"The QFI norm along [1, 1, 1, 1] at [11.93805208 11.93805208 3.2533421 5.02652273] is 5.40406149.\n",
"The QFI norm along [1, 1, 1, 1] at [12.25221135 12.25221135 3.2533421 5.02652273] is 5.87599852.\n",
"The QFI norm along [1, 1, 1, 1] at [12.56637061 12.56637061 3.2533421 5.02652273] is 5.99962501.\n"
]
}
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 9,
"source": [
"# 创建图像\n",
"fig = plt.figure(figsize=(9, 6))\n",
"ax = fig.add_subplot(111)\n",
"# 绘制 QFIM 投影\n",
"ax.plot(thetas, list_qfisher_norm, 's', markersize=11, markerfacecolor='none')\n",
"analytical_qfi_norm = 4 + 2 * np.sin(thetas) + 2 * np.cos(thetas) - 2 * np.cos(thetas) * np.sin(thetas)\n",
"ax.plot(thetas, analytical_qfi_norm, linestyle=(0, (5, 3)))\n",
"# 设置图例,标签,刻度\n",
"ax.legend(\n",
" ['get_qfisher_norm()', '$4+2\\\\sin\\\\theta+2\\\\cos\\\\theta-2\\\\sin\\\\theta\\\\cos\\\\theta$'], \n",
" loc='best', prop= {'size': label_font_size}, frameon=False,\n",
")\n",
"ax.set_xlabel('$\\\\theta$', fontsize=label_font_size)\n",
"ax.set_ylabel('QFI norm along $v=(1,1,1,1)$', fontsize=label_font_size)\n",
"ax.set_ylim([-1, 9])\n",
"ax.tick_params(labelsize=label_font_size)"
],
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 648x432 with 1 Axes>"
],
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAjEAAAGDCAYAAADahUEXAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAAsTAAALEwEAmpwYAABbF0lEQVR4nO3dd3gU5drH8e+dQAq9F2kBpKp0FEQELFgQj+21K3ZB7BUb2MWjHsuxe8SuR0HFfhSkiFgQsAMCAipFpAURQkue94/ZhIRskt3NbmY3+/tc11xLZp6dvTPsbO59qjnnEBEREUk0KX4HICIiIhIJJTEiIiKSkJTEiIiISEJSEiMiIiIJSUmMiIiIJCQlMSIiIpKQqvgdQLQ1aNDAZWVl+R2GiIiIRMGcOXPWOucaBjtW6ZKYrKwsZs+e7XcYIiIiEgVm9mtJx9ScJCIiIglJSYyIiIgkJCUxIiIikpCUxIiIiEhCUhIjIiIiCUlJjIiIiCQkJTEiIiKSkJTEiIiISEJSEiMiIiIJSUmMiIiIJCQlMSIiIpKQlMSIiIhIQlISIyIiIglJSYyIiIgkJCUxIiIikpCUxIhIpbF06VKOOeYYGjZsiJlx1llnART5dzjOOusszCy6QUqBDz/8kCpVqrBgwYKCfQ899BD169dnw4YNPkYmiUJJjIjEzIMPPshzzz1XYa931llnMX36dK677jpefPFFLrzwwgp7bQnPzp07ueqqqzjttNPo2LFjwf4LL7yQ9PR0br/9dh+jk0RRxe8ARJJFv7FTWJGdE1LZZnUymTnqoBhHFHsPPvggWVlZEdWChGvbtm3MmDGDiy++mKuvvrrIsZycHFJTU2Meg4Ru/PjxzJ8/n1dffbXI/oyMDIYPH85dd93FjTfeSP369X2KUBKBkhiRCrIiO4dlY4eEVDZr1PsxjqbyWb16Nc456tWrV+xYRkaGDxGFb9OmTdSsWdPvMIKKdmyPPfYYXbp0oWvXrsWOnX766YwZM4bnnnuOq666KmqvKZWPmpNEhGXLlnH88cdTq1YtatWqxT/+8Q+WLl1KVlYWAwcOLFZ+8uTJDB48mDp16pCRkUGXLl144oknipQxM3799VemT5+OmRVsy5YtCyu2t99+m+7du5ORkUGLFi24+eabmTRpEmZW0FR11lln0apVKwBuvfXWgteaNm1aQSy71wa9//77DBgwgAYNGpCZmUnLli057rjjWLhwYbEYNm7cyIgRI2jUqBEZGRn069ePr776qlg55xyPP/44PXv2pFq1atSoUYNBgwYxderUIuWWLVuGmXHLLbfw2muv0bNnTzIzM7nkkktCvi633HILZsbPP//MDTfcQPPmzUlPT6dr16588MEHxcrv3LmTe+65h86dO5ORkUH9+vU59thj+eGHH8KKLf9aTpkyhb59+1KtWjWaN2/OPffcA8CGDRs499xzadSoEdWqVeOoo45i5cqVRV7jjz/+4LPPPuPII48M+ru1adOGDh06MH78+JCvhyQn1cSIJLl169bRv39/Vq9ezfDhw+nUqRMzZsxg0KBBbN68uVj5p556iuHDh9OnTx9uvPFGqlevzqRJkxgxYgS//PIL9957LwAvvvgiV1xxBQ0aNODGG28seH7Dhg1Dju2tt97i+OOPJysri9GjR1OlShWeffZZ3n+/aE3VhRdeSLdu3bjiiis49thjOe644wDo1KlT0PNOnz6do48+mr333pvrr7+eOnXqsHLlSiZPnszixYtp3759kfKHHXYYDRs2ZPTo0axbt45//etfDBkyhKVLlxapnTjjjDN49dVXOeGEEzj77LPZtm0bL7/8MoceeihvvvkmRx99dJHzTpw4kYcffpgRI0YwfPhwatWqFfK1yTds2DCqVq3K1Vdfzfbt23nwwQc55phjWLhwIVlZWQXlTjvtNF5//XUOPfRQRowYwR9//MGjjz5K3759mTFjBt27dw85tm+++YZ3332XCy64gDPPPJPXX3+dUaNGkZGRwfPPP09WVha33HILixcv5uGHH+bMM89k8uTJRa4/wL777lvi79W3b19eeukl/v77b2rUqBH2dZEk4ZyrVFvPnj2dSDxqdd17MSlbXtdcc40D3EsvvRR0/4ABAwr2rVy50qWnp7tTTjml2HkuvfRSl5KS4n755ZeCfa1atSry/HDs3LnTtWjRwtWvX9+tWbOmYH92drZr2bKlA9yzzz5bsH/p0qUOcGPGjCl2LsANGzas4OcrrrjCAW716tWlxjBs2DAHuBEjRhTZ//rrrzvAPfHEEwX73nzzTQe4J598skjZHTt2uJ49e7qsrCyXl5dXJNYqVaq4efPmlXUpghozZowD3JAhQwrO65xzs2bNcoAbNWpUwb6PP/7YAe7EE08sUvbbb791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HpAVQtnTgamhnDcWm5IYkfKZM2eOS01Ndffff39ESczUqVMd4KZOnRrW877++muXnZ1dbP+NN97oAPfvf/87rPNFW25uruvcubPr0aOHy8vLK3Ls7rvvdoCbOXNmyOeL5DrF+zUKJtrXLRLxft3i4RqFo6LjLS2JCak5yTl3t3MuxTm3LISyLznnBoVyXhGJL7m5uZx//vkcfvjhHHfccRX62r169aJ27eLjAk46yVu95Mcffyyyf+vWrdxyyy106NCBatWqUadOHfbZZx+uueaagjLB+i0899xzmBlTpkzhvvvuo23btqSnp9O+fftSV9f+6KOPmDdvHpdeeilmVuRYWloaABs3bgz79w5HuNcIYPv27fzzn/+kW7duVKtWjdq1a9OrVy8eeaRoy//atWsZOXIkLVq0IC0tjRYtWjBy5EjWrSuyFm9I172wRLxu8f7e0v/pLnE1Y6+I+OuBBx5gwYIFvPHGG36HUmD58uUANG7cuMj+kSNHMm7cOM4880yuvPJKdu7cyaJFi5gyZUpI573hhhvIycnhwgsvJD09nccff5yzzjqLPffck379+hUr/9prr5Gamkr//v1Zu3ZtkWOrV68GoGbNmpH8iuVW0jXavn07hx12GNOmTWPw4MGcfvrpZGRk8MMPP/Dmm28W9HfauHEj+++/P4sXL+acc86hR48efPPNNzz++ONMmTKFWbNmFfxu4V73RLxu8fze0v/pbkqqoknUTc1JUiHGHVnyNvelii8fBUuWLHHVqlVzY8eOdc45t3Tp0gptTgpm586drm/fvq5KlSpuwYIFRY7VrVvXHXHEESHF8uyzzxbse/bZZx3gunXr5rZt21awf/ny5S4tLc2dfPLJQc/VsmVLB5S6rVixIuTfLVrXqbRrdM899zjAXX/99cWel5ubW/DvG264wQHu0UcfLVLmkUcecYC76aabCvaFct0Li/Z1i5ZEfW8l4/8ppTQnqSZGRAAYPnw4bdq04corrwz5OXl5eaxfv77Ivvxq5I0bNxb7llavXj1SUkKfY/Pyyy/niy++4K677qJDhw5FjtWuXZuffvqJH3/8kb333jvkc+a76KKLCqq+AZo1a0b79u1ZtGhRsbJr167lt99+49hjj+Wiiy4qdvzEE08kPT2dPfbYI+hrxfI6lXaNXn75ZerWrcvo0aOLPa/w+d966y0aNmzI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"
},
"metadata": {
"needs_background": "light"
}
}
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"可以看到程序的输出和解析结果是一致的。"
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"### 计算有效量子维数\n",
"\n",
"利用量桨,我们可以通过调用 `get_eff_qdim()` 方法方便地计算有效量子维数(effective quantum dimension, EQD)。以下是上面提到的 hardware-efficient 拟设的 EQD 计算示例。"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 10,
"source": [
"cir = circuit_hardeff_2qubit()\n",
"qf = QuantumFisher(cir)\n",
"print(cir)\n",
"print(f'The number of parameters is {len(cir.get_param().tolist())}.')\n",
"print(f'The EQD is {qf.get_eff_qdim()}. \\n')"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"--Ry(4.248)----*----Ry(1.233)--\n",
" | \n",
"--Ry(6.121)----x----Ry(4.717)--\n",
" \n",
"The number of parameters is 4.\n",
"The EQD is 3. \n",
"\n"
]
}
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"在这个例子中,EQD 比参数个数要少,这实际上可以通过控制电路上两个 $R_y$ 可以直接合并这一点上看出来。这可以通过替换其中一个 $R_y$ 门为 $R_x$ 门来修复,这会使得 EQD 增长 1。\n",
"\n",
"如果继续在电路上增加门,EQD 会无限增长吗?答案显然是不会,这是因为对于 $n$ 个量子比特,量子态的实数自由度为 $2\\cdot 2^n-2$,其中减 $2$ 是由于归一化和全局相位无关性这两条约束。这说明无论门的数量为多少,EQD 都不会超过 $2\\cdot 2^n-2$。我们可以通过下面的例子做一简单的验证。"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 11,
"source": [
"def circuit_hardeff_overparam():\n",
" cir = UAnsatz(2)\n",
" theta = 2 * np.pi * np.random.random(8)\n",
" theta = paddle.to_tensor(theta, stop_gradient=False, dtype='float64')\n",
" cir.ry(theta[0], which_qubit=0)\n",
" cir.ry(theta[1], which_qubit=1)\n",
" cir.rx(theta[2], which_qubit=0)\n",
" cir.rx(theta[3], which_qubit=1)\n",
" cir.cnot(control=[0, 1])\n",
" cir.ry(theta[4], which_qubit=0)\n",
" cir.ry(theta[5], which_qubit=1)\n",
" cir.rx(theta[6], which_qubit=0)\n",
" cir.rx(theta[7], which_qubit=1)\n",
"\n",
" return cir\n",
"\n",
"\n",
"cir = circuit_hardeff_overparam()\n",
"qf = QuantumFisher(cir)\n",
"print(cir)\n",
"print(f'The number of parameters is {len(cir.get_param().tolist())}.')\n",
"print(f'The EQD is {qf.get_eff_qdim()}. \\n')"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"--Ry(0.173)----Rx(5.837)----*----Ry(3.082)----Rx(3.997)--\n",
" | \n",
"--Ry(1.354)----Rx(0.536)----x----Ry(5.267)----Rx(5.647)--\n",
" \n",
"The number of parameters is 8.\n",
"The EQD is 6. \n",
"\n"
]
}
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"### 计算经典费舍信息和有效维数\n",
"\n",
"这里我们举一个简单的例子来展示如何利用量桨对于一个量子神经网络计算式 (16) 中的有效维数。\n",
"\n",
"首先,定义经典数据到量子数据的编码方式。"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 12,
"source": [
"def U_theta(x, theta, num_qubits, depth, encoding):\n",
" cir = UAnsatz(num_qubits)\n",
" if encoding == 'IQP':\n",
" S = [[i, i + 1] for i in range(num_qubits - 1)]\n",
" cir.iqp_encoding(x, num_repeats=1, pattern=S)\n",
" cir.complex_entangled_layer(theta, depth)\n",
" elif encoding == 're-uploading':\n",
" for i in range(depth):\n",
" cir.complex_entangled_layer(theta[i:i + 1], depth=1)\n",
" for j in range(num_qubits):\n",
" cir.rx(x[j], which_qubit=j)\n",
" cir.complex_entangled_layer(theta[-1:], depth=1)\n",
" else:\n",
" raise RuntimeError('Non-existent encoding method')\n",
" return cir"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"然后调用飞桨定义量子神经网络和相应的损失函数。"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 13,
"source": [
"import paddle.nn as nn\n",
"\n",
"class QuantumNeuralNetwork(nn.Layer):\n",
" def __init__(self, num_qubits, depth, encoding):\n",
" super().__init__()\n",
" self.num_qubits, self.depth, self.encoding = num_qubits, depth, encoding\n",
" if self.encoding == 'IQP':\n",
" self.theta = self.create_parameter(\n",
" shape=[self.depth, self.num_qubits, 3],\n",
" default_initializer=paddle.nn.initializer.Uniform(low=0.0,\n",
" high=2 *\n",
" np.pi),\n",
" dtype='float64',\n",
" is_bias=False)\n",
" elif self.encoding == 're-uploading':\n",
" self.theta = self.create_parameter(\n",
" shape=[self.depth + 1, self.num_qubits, 3],\n",
" default_initializer=paddle.nn.initializer.Uniform(low=0.0,\n",
" high=2 *\n",
" np.pi),\n",
" dtype='float64',\n",
" is_bias=False)\n",
" else:\n",
" raise RuntimeError('Non-existent encoding method')\n",
"\n",
" def forward(self, x):\n",
" if not paddle.is_tensor(x):\n",
" x = paddle.to_tensor(x)\n",
" cir = U_theta(x, self.theta, self.num_qubits, self.depth,\n",
" self.encoding)\n",
" cir.run_state_vector()\n",
" return cir.expecval([[1.0, 'z0']]) * paddle.to_tensor(\n",
" [0.5], dtype='float64') + paddle.to_tensor([0.5], dtype='float64')"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"最后,定义 CFIM 计算器并计算不同大小的训练集对应的有效维数。"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 17,
"source": [
"# 配置模型参数\n",
"num_qubits = 4\n",
"depth = 2\n",
"num_inputs = 100\n",
"num_thetas = 10\n",
"# 定义 CFIM 计算器\n",
"cfim = ClassicalFisher(model=QuantumNeuralNetwork,\n",
" num_thetas=num_thetas,\n",
" num_inputs=num_inputs,\n",
" num_qubits=num_qubits,\n",
" depth=depth,\n",
" encoding='IQP')\n",
"# 计算归一化的 CFIM\n",
"fim, _ = cfim.get_normalized_cfisher()\n",
"# 计算不同样本大小对应的有效维数\n",
"n = [5000, 8000, 10000, 40000, 60000, 100000, 150000, 200000, 500000, 1000000]\n",
"effdim = cfim.get_eff_dim(fim, n)"
],
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"running in get_gradient: 100%|##################################| 1000/1000 [02:05<00:00, 7.94it/s]\n"
]
}
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"画出有效维数与参数个数之比随训练集大小的变化规律。"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 19,
"source": [
"fig = plt.figure(figsize=(9, 6))\n",
"ax = fig.add_subplot(111)\n",
"print('the number of parameters:%s' % cfim.num_params)\n",
"ax.plot(n, np.array(effdim) / cfim.num_params)\n",
"label_font_size = 14\n",
"ax.set_xlabel('sample size', fontsize=label_font_size)\n",
"ax.set_ylabel('effective dimension / number of parameters', fontsize=label_font_size)\n",
"ax.tick_params(labelsize=label_font_size)"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"the number of parameters:24\n"
]
},
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 648x432 with 1 Axes>"
],
"image/png": "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"
},
"metadata": {
"needs_background": "light"
}
}
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"## 总结\n",
"\n",
"本教程从几何的角度简要介绍了经典费舍信息和量子费舍信息的概念及二者之间的关系,并以有效维数为例阐述了它们在量子机器学习中的应用,最后展示了如何调用量桨来具体地计算它们。"
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"_______\n",
"\n",
"## 参考文献\n",
"\n",
"[1] Meyer, Johannes Jakob. \"Fisher information in noisy intermediate-scale quantum applications.\" [arXiv preprint arXiv:2103.15191 (2021).](https://arxiv.org/abs/2103.15191)\n",
"\n",
"[2] Haug, Tobias, Kishor Bharti, and M. S. Kim. \"Capacity and quantum geometry of parametrized quantum circuits.\" [arXiv preprint arXiv:2102.01659 (2021).](https://arxiv.org/abs/2102.01659)\n",
"\n",
"[3] Stokes, James, et al. \"Quantum natural gradient.\" [Quantum 4 (2020): 269.](https://quantum-journal.org/papers/q-2020-05-25-269/)\n",
"\n",
"[4] Mari, Andrea, Thomas R. Bromley, and Nathan Killoran. \"Estimating the gradient and higher-order derivatives on quantum hardware.\" [Physical Review A 103.1 (2021): 012405.](https://journals.aps.org/pra/abstract/10.1103/PhysRevA.103.012405)\n",
"\n",
"[5] Datta, Nilanjana, and Felix Leditzky. \"A limit of the quantum Rényi divergence.\" [Journal of Physics A: Mathematical and Theoretical 47.4 (2014): 045304.](https://iopscience.iop.org/article/10.1088/1751-8113/47/4/045304)\n",
"\n",
"[6] Abbas, Amira, et al. \"The power of quantum neural networks.\" [Nature Computational Science 1.6 (2021): 403-409.](https://www.nature.com/articles/s43588-021-00084-1)"
],
"metadata": {}
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
\ No newline at end of file
{
"cells": [
{
"cell_type": "markdown",
"source": [
"# Quantum Fisher Information\n",
"\n",
"<em> Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved. </em>"
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"## Overview\n",
"\n",
"In this tutorial, we briefly introduce the concepts of the classical and quantum Fisher information, along with their applications in quantum machine learning, and show how to compute them with Paddle Quantum."
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"## Background\n",
"\n",
"The quantum Fisher information (QFI) originates from the field of quantum sensing and have been versatile tools to study parameterized quantum systems [[1]](https://arxiv.org/abs/2103.15191), such as characterizing the overparameterization [[2]](https://arxiv.org/abs/2102.01659) and performing the quantum natural gradient descent [[3]](https://arxiv.org/abs/1909.02108). The QFI is a quantum analogue of the classical Fisher information (CFI). The CFI characterizes the sensibility of a parameterized **probability distribution** to parameter changes, while the QFI characterizes the sensibility of a parameterized **quantum state** to parameter changes.\n",
"\n",
"In a traditional introduction, the CFI will appear as a quantity of parameter estimation in mathematical statistics, which might be complicated and confusing for the beginners. This tutorial will introduce the CFI from a geometric point of view, which is not only helpful for intuitive understanding, but also easier to see the relationship between the CFI and QFI."
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"### Classical Fisher information\n",
"\n",
"Let's consider the classical Fisher information first. Suppose we now have a parameterized probability distribution $p(\\boldsymbol{x};\\boldsymbol{\\theta})$. Here comes a question:\n",
"\n",
"- How much does a small parameter change result in the probability distribution change ?\n",
"\n",
"Since the question sounds like a perturbation problem, an intuition is to perform something like the Taylor expansion. But before expansion, we need to know which function to expand, i.e. we need to quantify the probability distribution change first. More formally, we need to define a distance measure between any two probability distributions, denoted by $d(p(\\boldsymbol{x};\\boldsymbol{\\theta}),p(\\boldsymbol{x};\\boldsymbol{\\theta}'))$, or $d(\\boldsymbol{\\theta},\\boldsymbol{\\theta}')$ for short.\n",
"\n",
"Generally, a legal distance measure is supposed to be non-negative and equal to zero if and only if two points are identical, i.e.\n",
"\n",
"$$\n",
"\\begin{aligned}\n",
"&d(\\boldsymbol{\\theta},\\boldsymbol{\\theta}')\\geq 0,\\\\\n",
"&d(\\boldsymbol{\\theta},\\boldsymbol{\\theta}')=0~\\Leftrightarrow~\\boldsymbol{\\theta}=\\boldsymbol{\\theta}'.\n",
"\\end{aligned}\n",
"\\tag{1}\n",
"$$\n",
"\n",
"Considering the expansion of a small distance $d(\\boldsymbol{\\theta},\\boldsymbol{\\theta}+\\boldsymbol{\\delta})$, the conditions above lead to\n",
"\n",
"$$\n",
"\\begin{aligned}\n",
"&d(\\boldsymbol{\\theta},\\boldsymbol{\\theta})=0~\\Rightarrow~\\text{the zero order}=0,\\\\\n",
"&d(\\boldsymbol{\\theta},\\boldsymbol{\\theta}+\\boldsymbol{\\delta})\\geq 0~\\Rightarrow~\\boldsymbol{\\delta}=0~\\text{takes minimum}\n",
"~\\Rightarrow~\\text{the first order}=0.\n",
"\\end{aligned}\n",
"\\tag{2}\n",
"$$\n",
"\n",
"Thus, the second order is the lowest order that does not vanish in the expansion. So the expansion can be written as\n",
"\n",
"$$\n",
"\\begin{aligned}\n",
"d(\\boldsymbol{\\theta},\\boldsymbol{\\theta}+\\boldsymbol{\\delta})\n",
"=\\frac{1}{2}\\sum_{ij}\\delta_iM_{ij}\\delta_j+O(\\|\\boldsymbol{\\delta}\\|^3) \n",
"=\\frac{1}{2} \\boldsymbol{\\delta}^T M \\boldsymbol{\\delta} + O(\\|\\boldsymbol{\\delta}\\|^3),\n",
"\\end{aligned}\n",
"\\tag{3}\n",
"$$\n",
"\n",
"where\n",
"\n",
"$$\n",
"M_{ij}(\\boldsymbol{\\theta})=\\left.\\frac{\\partial^2}{\\partial\\delta_i\\partial\\delta_j}d(\\boldsymbol{\\theta},\\boldsymbol{\\theta}+\\boldsymbol{\\delta})\\right|_{\\boldsymbol{\\delta}=0},\n",
"\\tag{4}\n",
"$$\n",
"\n",
"is exactly the Hessian matrix of the distance expansion, which is called [metric](http://en.wikipedia.org/wiki/Metric_tensor) of manifold in the context of differentiable geometry. The brief derivation above tells us that we can approximate a small distance as a quadratic form of the corresponding parameters, as shown in Fig.1, and the coefficient matrix of the quadratic form is exactly the Hessian matrix from the distance expansion, up to a $1/2$ factor.\n",
"\n",
"![feature map](./figures/FIM-fig-Sphere-metric.png \"Figure 1. Approximate a small distance on the 2-sphere as a quadratic form\")\n",
"<div style=\"text-align:center\">Figure 1. Approximate a small distance on the 2-sphere as a quadratic form </div>\n",
"\n",
"If the distance measure is specified to be the relative entropy / KL divergence, i.e.\n",
"$$\n",
"d_{\\mathrm{KL}}(\\boldsymbol{\\theta}, \\boldsymbol{\\theta}^{\\prime})=\\sum_{\\boldsymbol{x}} p(\\boldsymbol{x};\\boldsymbol{\\theta}) \\log \\frac{p(\\boldsymbol{x};\\boldsymbol{\\theta})}{p(\\boldsymbol{x};\\boldsymbol{\\theta}^{\\prime})}.\n",
"\\tag{5}\n",
"$$\n",
"\n",
"The corresponding Hessian matrix\n",
"\n",
"$$\n",
"\\begin{aligned}\n",
"\\mathcal{I}_{ij}(\\boldsymbol{\\theta})&= \\left.\\frac{\\partial^2}{\\partial\\delta_i\\partial\\delta_j}d_{\\mathrm{KL}}(\\boldsymbol{\\theta},\\boldsymbol{\\theta}+\\boldsymbol{\\delta})\\right|_{\\boldsymbol{\\delta}=0}\\\\\n",
"&=-\\sum_{\\boldsymbol{x}} p(\\boldsymbol{x};\\boldsymbol{\\theta}) \\partial_{i} \\partial_{j} \\log p(\\boldsymbol{x};\\boldsymbol{\\theta})\n",
"=\\mathbb{E}_{\\boldsymbol{x}}[-\\partial_{i} \\partial_{j} \\log p(\\boldsymbol{x};\\boldsymbol{\\theta})] \\\\\n",
"&=\\sum_{\\boldsymbol{x}} \\frac{1}{p(\\boldsymbol{x};\\boldsymbol{\\theta})} \\partial_i p(\\boldsymbol{x};\\boldsymbol{\\theta}) \\cdot \\partial_j p(\\boldsymbol{x};\\boldsymbol{\\theta})\n",
"=\\mathbb{E}_{\\boldsymbol{x}}[\\partial_i\\log p(\\boldsymbol{x};\\boldsymbol{\\theta})\\cdot \\partial_j \\log p(\\boldsymbol{x};\\boldsymbol{\\theta})].\n",
"\\end{aligned}\n",
"\\tag{6}\n",
"$$\n",
"\n",
"is the so-called classical Fisher information matrix (CFIM), with large entries indicating large sensibility to the corresponding parameter changes. Here we use the notation $\\partial_i=\\partial/\\partial \\theta_i$.\n",
"\n",
"Why is $\\mathcal{I}(\\boldsymbol{\\theta})$ called \"information\"? Geometrically, the CFIM characterizes the sensitivity / sharpness of a probability distribution in the vicinity of $\\boldsymbol{\\theta}$. The more sensitive it is to a parameter change, the easier one can discriminate it from others, the fewer samples are needed to discriminate it, the more information per sample can give.\n",
"\n",
"The measurement outcomes from a parameterized quantum circuit (PQC) form a parameterized probability distribution. So one can define a CFIM for each kind of measurement on a PQC. Currently, the main challenge of calculating CFIM on NISQ devices is that the number of possible measurement outputs increases exponentially with the number of qubits, which means that there may be many measurement outputs with low probabilities that never appear, leading to divergence in CFIM calculations. Possible solutions includes neglecting small probabilities (cause diverge) and Bayesian updating [[1]](https://arxiv.org/abs/2103.15191)."
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"### Quantum Fisher information\n",
"\n",
"The quantum Fisher information is a natural quantum analogue of the classical notion above, where the expanded distance is not defined between two probability distributions, but two quantum states. A common choice is the fidelity distance \n",
"\n",
"$$\n",
"d_f(\\boldsymbol{\\theta},\\boldsymbol{\\theta}')=2-2|\\langle\\psi(\\boldsymbol{\\theta})|\\psi(\\boldsymbol{\\theta}')\\rangle|^2.\n",
"\\tag{7}\n",
"$$\n",
"\n",
"where an additional factor $2$ here is manually multiplied to make the subsequent results resemble the CFIM. Hence formally, the quantum Fisher information matrix (QFIM) at a parameterized pure quantum state $|\\psi(\\boldsymbol{\\theta})\\rangle, \\boldsymbol{\\theta}\\in\\mathbb{R}^m$ is the Hessian matrix of the fidelity distance expansion, i.e.\n",
"\n",
"$$\n",
"\\begin{aligned}\n",
"\\mathcal{F}_{ij}(\\boldsymbol{\\theta})\n",
"&= \\left.\\frac{\\partial^2}{\\partial\\delta_i\\partial\\delta_j}d_{f}(\\boldsymbol{\\theta},\\boldsymbol{\\theta}+\\boldsymbol{\\delta})\\right|_{\\boldsymbol{\\delta}=0} \\\\\n",
"&=4 \\operatorname{Re}\\left[\\left\\langle\\partial_{i} \\psi \\mid \\partial_{j} \\psi\\right\\rangle - \\left\\langle\\partial_{i} \\psi \\mid \\psi\\right\\rangle\\left\\langle\\psi \\mid \\partial_{j} \\psi\\right\\rangle\\right],\n",
"\\end{aligned}\n",
"\\tag{8}\n",
"$$\n",
"\n",
"where we have omitted the argument $\\boldsymbol{\\theta}$ for simplicity. Similar to the CFIM, the QFIM characterizes the sensibility of a parameterized quantum state to a small change of parameters. In addition, it is worth mentioning that the QFIM can be seen as the real part of a complex matrix called the quantum geometric tensor, or say the Fubini-Study metric [[1]](https://arxiv.org/abs/2103.15191).\n",
"\n",
"Currently, the community has developed some techniques to calculate the QFIM for pure states on NISQ devices, among which the two most straight methods are\n",
"\n",
"- applying the second order parameter shift rule [[4]](https://arxiv.org/abs/2008.06517)\n",
"$$\n",
"\\begin{aligned}\n",
"\\mathcal{F}_{i j}=-\\frac{1}{2} \\Big(&|\\langle\\psi(\\boldsymbol{\\theta}) \\mid \\psi(\\boldsymbol{\\theta}+(\\boldsymbol{e}_{i}+\\boldsymbol{e}_{j}) \\frac{\\pi}{2})\\rangle|^{2}\n",
"-|\\langle\\psi(\\boldsymbol{\\theta}) \\mid \\psi(\\boldsymbol{\\theta}+(\\boldsymbol{e}_{i}-\\boldsymbol{e}_{j}) \\frac{\\pi}{2})\\rangle|^{2}\\\\\n",
"-&|\\langle\\psi(\\boldsymbol{\\theta}) \\mid \\psi(\\boldsymbol{\\theta}-(\\boldsymbol{e}_{i}-\\boldsymbol{e}_{j}) \\frac{\\pi}{2})\\rangle|^{2}\n",
"+|\\langle\\psi(\\boldsymbol{\\theta}) \\mid \\psi(\\boldsymbol{\\theta}-(\\boldsymbol{e}_{i}+\\boldsymbol{e}_{j}) \\frac{\\pi}{2})\\rangle|^{2}\\Big),\n",
"\\end{aligned}\n",
"\\tag{9}\n",
"$$\n",
"where $\\boldsymbol{e}_{i}$ denotes the unit vector corresponding to $\\theta_i$.\n",
"\n",
"- applying the finite difference expression to calculate the projection along a certain direction [[1]](https://arxiv.org/abs/2103.15191)\n",
"$$\n",
"\\boldsymbol{v}^{T} \\mathcal{F} \\boldsymbol{v} \\approx \\frac{4 d_{f}(\\boldsymbol{\\theta}, \\boldsymbol{\\theta}+\\epsilon \\boldsymbol{v})}{\\epsilon^{2}}.\n",
"\\tag{10}\n",
"$$\n",
"which can be regarded as the quantum analogue of the famed Fisher-Rao norm.\n",
"\n",
"For mixed states, the QFIM can be defined by the expansion of the Bures fidelity distance\n",
"\n",
"$$\n",
"d_B(\\boldsymbol{\\theta},\\boldsymbol{\\theta}')\\equiv \n",
"2-2\\left[\\text{Tr}\\left([\\sqrt{\\rho(\\boldsymbol{\\theta})} \\rho(\\boldsymbol{\\theta}')\\sqrt{\\rho(\\boldsymbol{\\theta})}]^{1/2}\\right)\\right]^2,\n",
"\\tag{11}\n",
"$$\n",
"\n",
"or equivalently ($\\log x\\sim x-1$), the $\\alpha=1/2$ \"sandwiched\" Rényi relative entropy [[5]](https://arxiv.org/abs/1308.5961)\n",
"\n",
"$$\n",
"\\begin{aligned}\n",
"d_R(\\boldsymbol{\\theta},\\boldsymbol{\\theta}') &\\equiv 2\\widetilde{D}_{\\alpha=1/2}(\\rho(\\boldsymbol{\\theta'}) \\| \\rho(\\boldsymbol{\\theta})), \\\\\n",
"\\widetilde{D}_{\\alpha}(\\rho \\| \\sigma) \n",
"&\\equiv \n",
"\\frac{1}{\\alpha-1} \\log \\operatorname{Tr}\\left[\\left(\\sigma^{\\frac{1-\\alpha}{2 \\alpha}} \\rho \\sigma^{\\frac{1-\\alpha}{2 \\alpha}}\\right)^{\\alpha}\\right].\\\\\n",
"\\end{aligned}\n",
"\\tag{12}\n",
"$$\n",
"\n",
"Please see the review [[1]](https://arxiv.org/abs/2103.15191) for more details."
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"### The relation between CFIM and QFIM\n",
"\n",
"By definition, for a parameterized quantum circuit, the CFIM depends on the measurement bases while the QFIM does not. In fact, one can prove that the QFIM of a quantum state $\\rho(\\boldsymbol{\\theta})$ is an upper bound of the CFIM obtained by arbitrary measurement from the same quantum state, i.e.\n",
"\n",
"$$\n",
"\\mathcal{I}[\\mathcal{E}[\\rho(\\boldsymbol{\\theta})]]\\leq \\mathcal{F}[\\rho(\\boldsymbol{\\theta})],~\\forall\\mathcal{E},\n",
"\\tag{13}\n",
"$$\n",
"\n",
"where $\\mathcal{E}$ denotes the quantum operation corresponding to the measurement, and the inequality between two positive matrices means that the large minus the small is still a positive matrix. This is a natural result since measurements can not extract more information than the quantum state itself, which mathematically stems from the monotonicity of the fidelity distance with respect to trace-preserving quantum operations [[1]](https://arxiv.org/abs/2103.15191)."
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"### Application: effective dimension\n",
"\n",
"The maximal rank of the CFIM / QFIM over the parameter space $\\Theta$ is a quantity to characterize the **capacity** of a classical / quantum neural network, called effective classical / quantum dimension\n",
"\n",
"$$\n",
"d_{\\text{eff}}=\\underset{\\boldsymbol{\\theta}\\in\\Theta} {\\max}\n",
"\\operatorname{rank}{\\mathcal{F}}(\\boldsymbol{\\theta}).\n",
"\\tag{14}\n",
"$$\n",
"\n",
"The rank captures in how many directions parameter changes will result in the probability distribution / quantum state changes. A not-full rank means that some changes of parameters can not actually change the probability distribution / quantum state, or say there are redundant degrees of freedom of parameters that can be projected out and the model is therefore overparameterized. On the other hand, a larger effective dimension corresponds to more directions that can be extended, suggesting a more extensive space occupied by the model, i.e. a larger capacity.\n",
"\n",
"In the context of machine learning, the so-called empirical CFIM [[6]](https://arxiv.org/abs/2011.00027) is more widely used, which is defined by a summation over samples instead of the expectation in the original definition\n",
"\n",
"$$\n",
"\\tilde{\\mathcal{I}}_{ij}(\\boldsymbol{\\theta})\n",
"=\\frac{1}{n}\\sum_{k=1}^{n}\n",
"\\partial_i\\log p(x_k,y_k;\\boldsymbol{\\theta})\n",
"\\partial_j\\log p(x_k,y_k;\\boldsymbol{\\theta}),\n",
"\\tag{15}\n",
"$$\n",
"\n",
"where $(x_k,y_k)^{n}_{k=1}$ are identical independent distributed training data drawn from the distribution $p(x,y;\\boldsymbol{\\theta})=p(y|x;\\boldsymbol{\\theta})p(x)$. Clearly, the empirical CFIM can converge to the CFIM in the limit of infinite samples if (1) the model has been well-trained and (2) the model has enough capacity to cover the underlying data distribution. The advantage of the empirical CFIM is that it can be calculated directly using the training data at hand, instead of calculating the original integral by generating new samples. \n",
"\n",
"By use of the empirical CFIM, a variant of the effective dimension can be defined as\n",
"\n",
"$$\n",
"d_{\\text{eff}}(\\gamma, n)=\n",
"2 \\frac{\\log \\left(\\frac{1}{V_{\\Theta}} \\int_{\\Theta} \\sqrt{\\operatorname{det}\\left( 1 + \\frac{\\gamma n}{2 \\pi \\log n} \\hat{\\mathcal{I}}( \\boldsymbol{\\theta})\\right)} \\mathrm{d} \\boldsymbol{\\theta} \\right)}\n",
"{\\log \\left(\\frac{\\gamma n}{2 \\pi \\log n}\\right)},\n",
"\\tag{16}\n",
"$$\n",
"\n",
"where $V_{\\Theta}:=\\int_{\\Theta} \\mathrm{d} \\boldsymbol{\\theta} \\in \\mathbb{R}_{+}$ is the volume of the parameter space. $\\gamma\\in(0,1]$ is an artificial tunable parameter. $\\hat{\\mathcal{I}} (\\boldsymbol{\\theta}) \\in \\mathbb{R}^{d\\times d}$ is the normalized empirical CFIM\n",
"\n",
"$$\n",
"\\hat{\\mathcal{I}}_{i j}(\\boldsymbol{\\theta}):= \\frac{V_{\\Theta} d }{\\int_{\\Theta} \\operatorname{Tr}(F( \\boldsymbol{\\theta} ) \\mathrm{d} \\theta} \\tilde{\\mathcal{I}}_{i j}(\\boldsymbol{\\theta}).\n",
"\\tag{17}\n",
"$$\n",
"\n",
"This definition might be strange and confusing at first glance, which is far more complicated than the maximal rank of the CFIM. However, it can converge to the maximal rank of the CFIM in the limit of infinite samples $n\\rightarrow \\infty$ [[6]](https://arxiv.org/abs/2011.00027). Regardless of the coefficients and the logarithm, the effective dimension here can be seen roughly as the geometric mean of the spectrum of the normalized CFIM plus an identity, then averaging over the parameter space. Associated with the inequality between the geometric mean and the arithmetic mean, we may expect that a more uniform empirical CFIM spectrum leads to a larger effective dimension, which is consistent with our natural impression. In this sense, it is a \"soft\" version of the effective dimension.\n",
"\n",
"In addition, the Fisher information can not only provide an capacity measure, but also can serve as an indicator of trainability. If the entries of the Fisher information vanish exponentially with the system size averaging over the parameter space, i.e. the sensitivity becomes exponentially small, we can not distinguish them efficiently, which indicates the existence of barrens plateaus [[6]](https://arxiv.org/abs/2011.00027)."
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"## Paddle Quantum Implementation"
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"### Calculate the QFIM\n",
"\n",
"With Paddle Quantum, one can obtain the QFIM conveniently by the following steps.\n",
"\n",
"1. Define a quantum circuit using `UAnsatz`.\n",
"2. Define a `QuantumFisher` class as a calculator of the QFIM.\n",
"3. Use the method `get_qfisher_matrix()` to calculate the QFIM.\n",
"\n",
"The calculator `QuantumFisher` will keep track of the change of the circuit `UAnsatz`.\n",
"\n",
"Now let's code. Firstly, import packages."
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 1,
"source": [
"import paddle\n",
"from paddle_quantum.circuit import UAnsatz\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from paddle_quantum.utils import QuantumFisher, ClassicalFisher\n",
"import warnings\n",
"warnings.filterwarnings(\"ignore\")"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"Then, define a quantum circuit. As a simple example, we exploit a single qubit parameterized by two Bloch angles\n",
"\n",
"$$\n",
"|\\psi(\\theta,\\phi)\\rangle=R_z(\\phi)R_y(\\theta)|0\\rangle=e^{-i\\phi/2}\\cos\\frac{\\theta}{2}|0\\rangle+e^{i\\phi/2}\\sin\\frac{\\theta}{2}|1\\rangle.\n",
"\\tag{18}\n",
"$$\n",
"\n",
"The corresponding QFIM can be directly calculated using Eq.(8). The analytical result reads\n",
"\n",
"$$\n",
"\\mathcal{F}(\\theta,\\phi)=\\left(\\begin{matrix}\n",
"1&0\\\\\n",
"0&\\sin^2\\theta\n",
"\\end{matrix}\\right).\n",
"\\tag{19}\n",
"$$"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 2,
"source": [
"def circuit_bloch():\n",
" cir = UAnsatz(1)\n",
" theta = 2 * np.pi * np.random.random(2)\n",
" theta = paddle.to_tensor(theta, stop_gradient=False, dtype='float64')\n",
" cir.ry(theta[0], which_qubit=0)\n",
" cir.rz(theta[1], which_qubit=0)\n",
" \n",
" return cir"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 3,
"source": [
"cir = circuit_bloch()\n",
"print(cir)"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"--Ry(1.888)----Rz(2.181)--\n",
" \n"
]
}
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"Define a QFIM calculator and calculate the QFIM element $\\mathcal{F}_{\\phi\\phi}$ corresponding to different $\\theta$."
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 4,
"source": [
"qf = QuantumFisher(cir)\n",
"# Record the QFIM element F_{phi,phi}\n",
"list_qfisher_elements = []\n",
"num_thetas = 21\n",
"thetas = np.linspace(0, np.pi, num_thetas)\n",
"for theta in thetas:\n",
" list_param = cir.get_param().tolist()\n",
" list_param[0] = theta\n",
" cir.update_param(list_param)\n",
" # Calculate the QFIM\n",
" qfim = qf.get_qfisher_matrix()\n",
" print(f'The QFIM at {np.array(list_param)} is \\n {qfim.round(14)}.')\n",
" list_qfisher_elements.append(qfim[1][1])"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"The QFIM at [0. 2.18107874] is \n",
" [[1. 0.]\n",
" [0. 0.]].\n",
"The QFIM at [0.15707963 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.02447174]].\n",
"The QFIM at [0.31415927 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.0954915]].\n",
"The QFIM at [0.4712389 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.20610737]].\n",
"The QFIM at [0.62831853 2.18107874] is \n",
" [[ 1. -0. ]\n",
" [-0. 0.3454915]].\n",
"The QFIM at [0.78539816 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.5]].\n",
"The QFIM at [0.9424778 2.18107874] is \n",
" [[ 1. -0. ]\n",
" [-0. 0.6545085]].\n",
"The QFIM at [1.09955743 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.79389263]].\n",
"The QFIM at [1.25663706 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.9045085]].\n",
"The QFIM at [1.41371669 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.97552826]].\n",
"The QFIM at [1.57079633 2.18107874] is \n",
" [[1. 0.]\n",
" [0. 1.]].\n",
"The QFIM at [1.72787596 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.97552826]].\n",
"The QFIM at [1.88495559 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.9045085]].\n",
"The QFIM at [2.04203522 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.79389263]].\n",
"The QFIM at [2.19911486 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.6545085]].\n",
"The QFIM at [2.35619449 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.5]].\n",
"The QFIM at [2.51327412 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.3454915]].\n",
"The QFIM at [2.67035376 2.18107874] is \n",
" [[ 1. -0. ]\n",
" [-0. 0.20610737]].\n",
"The QFIM at [2.82743339 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.0954915]].\n",
"The QFIM at [2.98451302 2.18107874] is \n",
" [[1. 0. ]\n",
" [0. 0.02447174]].\n",
"The QFIM at [3.14159265 2.18107874] is \n",
" [[1. 0.]\n",
" [0. 0.]].\n"
]
}
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"Plot the outputs of the QFIM element $\\mathcal{F}_{\\phi\\phi}$ as function of $\\theta$."
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 5,
"source": [
"# Create a figure\n",
"fig = plt.figure(figsize=(9, 6))\n",
"ax = fig.add_subplot(111)\n",
"# Plot the QFIM\n",
"ax.plot(thetas, list_qfisher_elements, 's', markersize=11, markerfacecolor='none')\n",
"# Plot sin^2 theta\n",
"ax.plot(thetas, np.sin(thetas) ** 2, linestyle=(0, (5, 3)))\n",
"# Set legends, labels, ticks\n",
"label_font_size = 18\n",
"ax.legend(['get_qfisher_matrix()[1][1]', '$\\\\sin^2\\\\theta$'], \n",
" prop= {'size': label_font_size}, frameon=False) \n",
"ax.set_xlabel('$\\\\theta$', fontsize=label_font_size)\n",
"ax.set_ylabel('QFIM element $\\\\mathcal{F}_{\\\\phi\\\\phi}$', fontsize=label_font_size)\n",
"ax.tick_params(labelsize=label_font_size)"
],
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 648x432 with 1 Axes>"
],
"image/png": "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4NSJGsU6kpxzepTw6NSpk5Ny2LHN7wRhaXHtu1HZtqKuueYaB7gXXngh6PIePXrsWrZq1SpXvXp1N2jQoGLHufzyy11KSopbunTprmUtWrQotH84du7c6Zo1a+YaNGjgsrOzdy1fv369a968uQPchAkTdi1ftmyZA9zo0aOLHQtwZ5111q7/jxgxwgFu9erVpWY466yzHOAuvvjiQstfeeUVB7jHH39817I33njDAe6JJ54otO2OHTtcp06dXFZWlsvLyyuUtUqVKm7RokVlnYqgRo8e7QDXv3//Xcd1zrkHHnjAAa5OnTpuxYoVu5avWbPGVa9e3Z1++umFjrNp06Zix160aJGrVq1asZ+7tN9nixYtHOCefPLJYutmzJhR7PflnHNz5851VatWdf3793e5ubnuqKOOctWqVXNfffVVoe2GDBniALdhw4ag39s5584991wHuLVr1+5a1qNHD9eiRYsS98mXnZ1d7DlSkqLbTZgwwQFuxowZZe7br18/570dli7/eee7T8c5N7qucwtf8jtJ3AHmuxLe8+OsvVDiQpVqfidICO+88w5NmjRh0KBBhZYX7ZgM8Nprr7Ft2zbOPfdc1q5dW+gxYMAA8vLymDZtWkRyffXVV/z222+cffbZZGRk7Fper149Lrroogodu149rwP+66+/zs6dO8vcfsSIEYX+n9/59eeff9617IUXXqBOnTocf/zxhc7L+vXrGTBgAMuXLy+0PUC/fv1KbMUK1eWXX17ozqX8O5QGDhxIs2bNdi1v2LAhbdq0KZahVq1agPeh9Z9//tnVn6ZNmzZBLwuWpn79+px99tkhb3/wwQdz++238+6779K9e3emTZvGmDFj6NixY6HtsrOzqVKlSqktaPl3nq1ZsyaszFKKQ4fBIZdCi0P9TpJQdMlMKs45NdtGwbJly+jSpUuxfg6NGjUiPT290LLFixcDcNRRR5V4vNWrV0ck1y+//AJA27Zti61r3759hY49bNgw3nrrLS655BKuvfZaDj/8cPr27cugQYOCXtJr2bJlof/nv/kWHA9n8eLFbNy4kd13L3namNWrVxe6HFf00lx5FM222267AbDnnnsW23a33Xbj119/LbRs4cKF3HTTTcycObPYJdJgxyhNq1atwr6b75prruHdd99l9uzZ9O7dm+HDhxfbJpQxeVxgvkyNGxVBKanQ906/UyQcFURScXMegL+WQr/7NIu9T/LfdJ5//nmaNGkSdJuib9CxqEGDBsybN4/Zs2czdepUPvnkE0aMGMHo0aN5//33OfTQwp+IS3qTzz8f+f9u2LAhL730Uonfd9999y30/7S0tAr8FKVnCyXzihUr6N69O3Xr1uWmm26iTZs21KpVCzNj+PDhpfYBCqY8P8/y5ct3deBesmQJmzZtKnanXcOGDdm5cycbNmzY1bpX1F9//bVrW5FYpoJIKubP72D67dD2WEjR0ymSsrKyWLJkCXl5eYVaidasWcP69esLbZvfwTYjI6PUVqJ8Ffm0nl9Y/fDDD8XWLVq0qNzHzZeamkrPnj133UX37bff0qlTJ26//fZinbZDsffee/PTTz9xyCGHULt27QrnqwyTJ09m06ZNvP322/Tq1avQunXr1lG9euEbFiLd+rJz504GDRrEzp07efDBB7niiiu4+OKLi432nF9I/vzzz3TuHHQCcZYsWULjxo0LDdooEbZzG2xaA+nNyt5WSqQ+RFJ+O7bC6+dDWgPoP06XzSJswIAB/PHHH7z88suFlt97773Ftj311FOpXr06o0ePJien+CCTGzZsYNu2bbv+X7t27V2f3MPVqVMn9thjDyZMmMDatWt3Lf/nn3+K3eIfroLHy9e2bVtq1qxZ7rxDhgwhLy+P6667Luj6SF1KjKT8VqSCrUYATz75JH/++Wex7Svy+wzmxhtv5IsvvuDhhx/msssu46qrruLFF1/kueeeK7RdftE6d+7coMfJzc1l/vz59OjRI2LZJIj/+xe8dKr3mizlpo/0Un7Tb4PsxfCv1yGt+KB7UjHXXnstL730EmeffTZffvklbdu2Zfbs2Xz22WdkZGQUahXYY489eOyxxzjvvPNo164dgwcPpkWLFmRnZ/Pdd9/x5ptvsmjRIrKysgA45JBDePrpp7npppto164dKSkpDBgwYFdH3tKkpqZy//33c+qpp9KlSxfOP/98qlSpwjPPPEODBg1YsWJFuX/m888/n99//53evXvTokULcnJymDRpEhs3biw0/k048m+1f/jhh1mwYAH9+/cnIyOD33//nc8//5wlS5bs6hcVK4455hjS0tIYPHgww4YNY7fddmPOnDm8//77tGrVqliH84r8PouaOnUqd999N2ecccauMaLuvPNOZs2axbBhwzjssMN2tUh26tSJli1b8v777xcbqRq82/I3b97MKaecElaG22+/HYAtW7YAXith/rLu3bvTvXv3sH+uot555x2++eYbwGvFKvh909PTg/48MevgC+HFk73X5D53+J0mbqkgkvL5ZZY3YupB58HeZV+iiWWZ6TVDHoE6M71mlNP8T0ZGBp9++ilXXXUVzzzzDGa2azDBgw46iJo1C2c5++yzad26Nffeey9PPPEE69evJyMjgzZt2nDbbbfRuHHjXdvecccd/PXXXzzyyCOsX78e5xzLli0L+Q305JNP5rXXXuPf//43t9xyC40aNWLo0KF0796d3r17l/tnHjx4MM8++yzPPfcc2dnZ1K1bl/bt2/Paa6+FPNJxMM888wy9evVi/Pjx3HXXXWzfvp3GjRvTsWNH7rrrrnIfN1patWrFBx98wPXXX8+dd95JamoqXbt23VWUFB1Es6K/z3xr1qxhyJAhtGzZslBrX9WqVXn55Zfp0KEDgwYN4rPPPqNatWqYGRdeeCHXX389q1evLtZxfeLEiTRu3JjjjjsurBw33VR4UNeFCxeycOFCAEaPHh2Rguj1118v1uKV/31btGgRXwXR3kdD53Ph80egdR/Ys+LnJymVdD++HhqHqERb/nZubHvnHuzo3LbNfqdJOmvXrnWAu/DCC/2OUkxJ49pI4tqwYYNr1KiRu+GGGwot/+OPP1zNmjXdAw88UGyfHj16uGbNmrns7OxC4xOFKy8vz2VnZwcdryh/HKI333zTZWdnu61bt5b7+2zYsMFlZ2e7008/PTbGIQpm2ybnHujgvTbnrPc7TcyilHGI1EIkQZU24WlD/mZs1d24d+epfHvzjISZ8DQW5eTkFGsJGjNmDOBNWinit7p163LrrbcycuTIQjPejxkzhj322IOLL7446H6//fYbDRs2JDU1NaQxp4JZvXp1iXdV5jv++OMBr7Uq2GSyoTj11FOZMmVKufatNNVqcd6mC3h823W8fccZXLnjklI31+t2cSqIJKiyJzw9k/xGWU14Gj3HHnssLVq0oGPHjuTl5fHxxx/z7rvvcthhh+16oY+UDRs2BO2QXVC1atWCTtKa6HJyctiwYUOZ2xW8LJlMLrroomKDco4bN45x48YF3X7s2LH8/fffABWaT6x+/fpMnTp11/+bNm266999+vQptK7o0ArhGDNmTNABUWPNtH+aUaXvtZw48y5OHHy5d/msBHrdLk4FkUgM69+/P88//zyTJ08mJyeHPfbYg6uuuorRo0eHPdBeWa644opifSqK6tGjR7FJP5PBpEmTQhrp2RW5K0yC69SpU0SOU61atRKHmWjSpEmZrUehOvDAAyNynErR7Srvzt+WvcreVgpRQSShycuD3O1QtYbfSZLKVVddxVVXXVUp32vkyJFlXlLIH225JD179kzIoqBoa4NIzEqtCl3O9ztFXFJBJGXLy4OPboSl02Hou1Aro+x9JO60b9++wlNvJKpItjaISGzSwIxSutyd8NalMPcR71bONI02KyISN7J/gg9Gea/lUioVRFKyHTnwymD45iXoeT0c8x+NRi0iEk+WTocvHoNXhmgk6zKoIJKg6rAFXjgZfvwAjr0Xel6rYkhEJN4ccpH3Gv7j+/DCSbC17Lslk5UKIiku529ernY7/DYXTnpKHfREROJZl/O91/Lf5sKz/WFTtt+JYpIKIimuWh1+dpkw6P9gv5P9TiMiIhW138nea/ran+GZPmSioqgoFURSXGoVRuy41JsfR0REEsPeR8OQt2DLWgakfu53mpij2+7Fk5cHBUaMjdUJTyWytm3bxrBhw/j444/Jzs6mSZMmXHbZZVx22WV+RxORMIX6ut2E20mpl8moSsgUT1QQCSz5GKbeDGe+AXW82ao1x01y2LlzJ40bN+ajjz6iZcuWfPvtt/Tp04fdd9+dU0891e94IhIGvW5XjC6ZJbvv34CXTgN0B1m8mjlzJmbGs88+G/a+tWrV4rbbbmOvvfYiJSWFAw88kIEDB/Lpp5+WuM+UKVPo2bMntWvXpmHDhgwbNoytW3U7r0jc+uNb+O+bfqfwnQqiZDbvaXjtHNijszcCdaB1SJLXjh07mD17Nvvvv3/Q9WPHjqVv3740adKE+++/nwEDBvDII49wxRVXVHJSEYmYT+6BV4fC/Gf8TuIrS8R5hyKlc+fObv78+X7HiDznYPa9MP122LsPnPIsVEvzO5WUU15eHtu3b6dq1aoVnvD1wgsvZMGCBcyZM4dq1aoVWjdt2jR69+7N3XffXWjm7759+zJjxgyys7OpW7duhb6/iPhg+xavIPp5ChxxkzdBbIKOO2dmXznnOgdbpxaiZJOXB1Nu8Iqh/U+D019UMRTnUlJSqFGjRoWLoSuvvJLPP/+cDz74oFgxlJeXxxVXXEGHDh2KTTbbs2dPtm/fzvfff1+h7y8iPqmW5r0X7H8aTL/Ne4/Iy/M7VaVTQZSMtqyDgy+G4x/3ZkaWmLV161ZuueUW2rRpQ1paGunp6ey3335cc801u7YJ1ofo2WefxcyYPn069957L61ataJ69eq0bt2a5557rtj3GT58OFOnTuXjjz8mI6P45L1Tpkxh0aJFXH755ViRT475xdOGDRoBVyRupVb13hMOvtibu/KtSyB3h9+pKpXuMks2KSlw/KNgKQnbJJpILr30Up555hmGDBnClVdeyc6dO/n555+ZPn16SPtff/315OTkcOGFF1K9enUee+wxhg4dyl577UXXrl0BuPzyy5k+fTozZsygYcOGQY8zadIkUlNT6datG2vXri20bvXq1QDUqVOnAj+piPguJQX63gVp9WHGHdC6D+xzgt+pKo0KomSUUrFLK1J5Jk+ezDHHHBO0VScU27ZtY968ebtacU4++WRatmzJww8/TNeuXfn111956KGHqF69Onvuueeu/bp168YHH3yw6/8zZswgNzeXVq1alfi9WrZsWa6MIhJDzKDHSNizBzTr4neaSqWCKNFtWgNvXwbH3gPpzf1OE30T+pW87sAzoMO/Knf7CqpXrx7//e9/+f7779l3333D3v+SSy4p1B8oMzOT1q1b8/PPPwPQokULyrqxYu3ataxYsYITTjiBSy65pNj6U089lerVq9O0adOw84lIjGp+sN8JKp0KojjXdcx0Vq7PCbpuD8tmYtU72d3Wc+73/8eKup01cFecGTduHIMHD2a//fajZcuW9OrViwEDBjBgwABSUsruAhis1aZBgwb8+uuvIWf45ZdfADjooIM46qijCq1btmwZf//9N2eccUbIxxOR+NJ1zHQyNnzHOuryu2tU6raZ6TXj9n1GBVGcW7k+h+VjgrRarF4EL1wFO7bBv97j5WYHhTwVR1w7O8yfMdrbV9Bxxx3H8uXLef/995k1axbTpk3j6aefplu3bkybNq3Y3WBFlXTnWTjDbWzatAkI3kfotddeA+C0004L+XgiEl/+XL+JOU0mwM6t3owGu7cvcdt4fp/RXWaJ6LcvYcIx3r/P+RCaHeRvHqmQ+vXrc+aZZ/Lkk0/yyy+/MHLkSGbPns1bb71VKd8/f2yhf/75p9Dy7du389hjj9GmTRv69SvlUqKI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"
},
"metadata": {
"needs_background": "light"
}
}
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"We can see that the outputs are consistent with the analytical results.\n",
"\n",
"Moreover, one can use the method `get_qfisher_norm()` to calculate the quantum Fisher-Rao norm in Eq.(10), i.e. the QFIM projection along a certain direction.\n",
"\n",
"As a different example, we exploit two qubits with a typical hardware-efficient ansatz\n",
"\n",
"$$\n",
"|\\psi(\\boldsymbol{\\theta})\\rangle=\\left[R_{y}\\left( \\theta_{3}\\right) \\otimes R_{y}\\left( \\theta_{4}\\right)\\right] \\text{CNOT}_{0,1}\\left[ R_{y}\\left( \\theta_{1}\\right) \\otimes R_{y}\\left( \\theta_{2}\\right)\\right]|00\\rangle.\n",
"\\tag{20}\n",
"$$\n",
"\n",
"The corresponding QFIM reads\n",
"\n",
"$$\n",
"\\mathcal{F}(\\theta_1,\\theta_2,\\theta_3,\\theta_4)=\\left(\\begin{array}{cc|cc}\n",
"1 & 0 & \\sin \\theta_{2} & 0 \\\\\n",
"0 & 1 & 0 & \\cos \\theta_{1} \\\\\n",
"\\hline \n",
"\\sin \\theta_{2} & 0 & 1 & -\\sin\\theta_1\\cos\\theta_2 \\\\\n",
"0 & \\cos \\theta_{1} & -\\sin\\theta_1\\cos\\theta_2 & 1\n",
"\\end{array}\\right).\n",
"\\tag{21}\n",
"$$\n",
"\n",
"Define the corresponding quantum circuit."
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 6,
"source": [
"def circuit_hardeff_2qubit():\n",
" cir = UAnsatz(2)\n",
" theta = 2 * np.pi * np.random.random(4)\n",
" theta = paddle.to_tensor(theta, stop_gradient=False, dtype='float64')\n",
" cir.ry(theta[0], which_qubit=0)\n",
" cir.ry(theta[1], which_qubit=1)\n",
" cir.cnot(control=[0, 1])\n",
" cir.ry(theta[2], which_qubit=0)\n",
" cir.ry(theta[3], which_qubit=1)\n",
"\n",
" return cir"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 7,
"source": [
"cir = circuit_hardeff_2qubit()\n",
"print(cir)"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"--Ry(2.614)----*----Ry(3.253)--\n",
" | \n",
"--Ry(2.906)----x----Ry(5.027)--\n",
" \n"
]
}
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"Define a QFIM calculator and calculate the quantum Fisher-Rao norm $\\boldsymbol{v}^T\\mathcal{F}\\boldsymbol{v}$ along the direction $\\boldsymbol{v}=(1,1,1,1)$ corresponding to different $\\theta$ (set $\\theta_1=\\theta_2=\\theta$)."
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 8,
"source": [
"qf = QuantumFisher(cir)\n",
"v = [1, 1, 1, 1]\n",
"# Record the QFI norm\n",
"list_qfisher_norm = []\n",
"num_thetas = 41\n",
"thetas = np.linspace(0, np.pi * 4, num_thetas)\n",
"for theta in thetas:\n",
" list_param = cir.get_param().tolist()\n",
" list_param[0] = theta\n",
" list_param[1] = theta\n",
" cir.update_param(list_param)\n",
" # Calculate the QFI norm\n",
" qfisher_norm = qf.get_qfisher_norm(v)\n",
" print(\n",
" f'The QFI norm along {v} at {np.array(list_param)} is {qfisher_norm:.8f}.'\n",
" )\n",
" list_qfisher_norm.append(qfisher_norm)"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"The QFI norm along [1, 1, 1, 1] at [0. 0. 3.2533421 5.02652273] is 5.99962501.\n",
"The QFI norm along [1, 1, 1, 1] at [0.31415927 0.31415927 3.2533421 5.02652273] is 5.93033916.\n",
"The QFI norm along [1, 1, 1, 1] at [0.62831853 0.62831853 3.2533421 5.02652273] is 5.84133590.\n",
"The QFI norm along [1, 1, 1, 1] at [0.9424778 0.9424778 3.2533421 5.02652273] is 5.84309143.\n",
"The QFI norm along [1, 1, 1, 1] at [1.25663706 1.25663706 3.2533421 5.02652273] is 5.93367838.\n",
"The QFI norm along [1, 1, 1, 1] at [1.57079633 1.57079633 3.2533421 5.02652273] is 5.99962501.\n",
"The QFI norm along [1, 1, 1, 1] at [1.88495559 1.88495559 3.2533421 5.02652273] is 5.86697827.\n",
"The QFI norm along [1, 1, 1, 1] at [2.19911486 2.19911486 3.2533421 5.02652273] is 5.38230779.\n",
"The QFI norm along [1, 1, 1, 1] at [2.51327412 2.51327412 3.2533421 5.02652273] is 4.49128513.\n",
"The QFI norm along [1, 1, 1, 1] at [2.82743339 2.82743339 3.2533421 5.02652273] is 3.28287364.\n",
"The QFI norm along [1, 1, 1, 1] at [3.14159265 3.14159265 3.2533421 5.02652273] is 1.97995933.\n",
"The QFI norm along [1, 1, 1, 1] at [3.45575192 3.45575192 3.2533421 5.02652273] is 0.87758767.\n",
"The QFI norm along [1, 1, 1, 1] at [3.76991118 3.76991118 3.2533421 5.02652273] is 0.25010151.\n",
"The QFI norm along [1, 1, 1, 1] at [4.08407045 4.08407045 3.2533421 5.02652273] is 0.26070618.\n",
"The QFI norm along [1, 1, 1, 1] at [4.39822972 4.39822972 3.2533421 5.02652273] is 0.90660775.\n",
"The QFI norm along [1, 1, 1, 1] at [4.71238898 4.71238898 3.2533421 5.02652273] is 2.01995733.\n",
"The QFI norm along [1, 1, 1, 1] at [5.02654825 5.02654825 3.2533421 5.02652273] is 3.32425271.\n",
"The QFI norm along [1, 1, 1, 1] at [5.34070751 5.34070751 3.2533421 5.02652273] is 4.52539873.\n",
"The QFI norm along [1, 1, 1, 1] at [5.65486678 5.65486678 3.2533421 5.02652273] is 5.40406149.\n",
"The QFI norm along [1, 1, 1, 1] at [5.96902604 5.96902604 3.2533421 5.02652273] is 5.87599852.\n",
"The QFI norm along [1, 1, 1, 1] at [6.28318531 6.28318531 3.2533421 5.02652273] is 5.99962501.\n",
"The QFI norm along [1, 1, 1, 1] at [6.59734457 6.59734457 3.2533421 5.02652273] is 5.93033916.\n",
"The QFI norm along [1, 1, 1, 1] at [6.91150384 6.91150384 3.2533421 5.02652273] is 5.84133590.\n",
"The QFI norm along [1, 1, 1, 1] at [7.2256631 7.2256631 3.2533421 5.02652273] is 5.84309143.\n",
"The QFI norm along [1, 1, 1, 1] at [7.53982237 7.53982237 3.2533421 5.02652273] is 5.93367838.\n",
"The QFI norm along [1, 1, 1, 1] at [7.85398163 7.85398163 3.2533421 5.02652273] is 5.99962501.\n",
"The QFI norm along [1, 1, 1, 1] at [8.1681409 8.1681409 3.2533421 5.02652273] is 5.86697827.\n",
"The QFI norm along [1, 1, 1, 1] at [8.48230016 8.48230016 3.2533421 5.02652273] is 5.38230779.\n",
"The QFI norm along [1, 1, 1, 1] at [8.79645943 8.79645943 3.2533421 5.02652273] is 4.49128513.\n",
"The QFI norm along [1, 1, 1, 1] at [9.1106187 9.1106187 3.2533421 5.02652273] is 3.28287364.\n",
"The QFI norm along [1, 1, 1, 1] at [9.42477796 9.42477796 3.2533421 5.02652273] is 1.97995933.\n",
"The QFI norm along [1, 1, 1, 1] at [9.73893723 9.73893723 3.2533421 5.02652273] is 0.87758767.\n",
"The QFI norm along [1, 1, 1, 1] at [10.05309649 10.05309649 3.2533421 5.02652273] is 0.25010151.\n",
"The QFI norm along [1, 1, 1, 1] at [10.36725576 10.36725576 3.2533421 5.02652273] is 0.26070618.\n",
"The QFI norm along [1, 1, 1, 1] at [10.68141502 10.68141502 3.2533421 5.02652273] is 0.90660775.\n",
"The QFI norm along [1, 1, 1, 1] at [10.99557429 10.99557429 3.2533421 5.02652273] is 2.01995733.\n",
"The QFI norm along [1, 1, 1, 1] at [11.30973355 11.30973355 3.2533421 5.02652273] is 3.32425271.\n",
"The QFI norm along [1, 1, 1, 1] at [11.62389282 11.62389282 3.2533421 5.02652273] is 4.52539873.\n",
"The QFI norm along [1, 1, 1, 1] at [11.93805208 11.93805208 3.2533421 5.02652273] is 5.40406149.\n",
"The QFI norm along [1, 1, 1, 1] at [12.25221135 12.25221135 3.2533421 5.02652273] is 5.87599852.\n",
"The QFI norm along [1, 1, 1, 1] at [12.56637061 12.56637061 3.2533421 5.02652273] is 5.99962501.\n"
]
}
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 9,
"source": [
"# Create a figure\n",
"fig= plt.figure(figsize=(9, 6))\n",
"ax = fig.add_subplot(111)\n",
"# Plot the QFI norm\n",
"ax.plot(thetas, list_qfisher_norm, 's', markersize=11, markerfacecolor='none')\n",
"analytical_qfi_norm = 4 + 2 * np.sin(thetas) + 2 * np.cos(thetas) - 2 * np.cos(thetas) * np.sin(thetas)\n",
"ax.plot(thetas, analytical_qfi_norm, linestyle=(0, (5, 3)))\n",
"# Set legends, labels, ticks\n",
"ax.legend(\n",
" ['get_qfisher_norm()', '$4+2\\\\sin\\\\theta+2\\\\cos\\\\theta-2\\\\sin\\\\theta\\\\cos\\\\theta$'], \n",
" loc='best', prop= {'size': label_font_size}, frameon=False,\n",
")\n",
"ax.set_xlabel('$\\\\theta$', fontsize=label_font_size)\n",
"ax.set_ylabel('QFI norm along $v=(1,1,1,1)$', fontsize=label_font_size)\n",
"ax.set_ylim([-1, 9])\n",
"ax.tick_params(labelsize=label_font_size)"
],
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 648x432 with 1 Axes>"
],
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAjEAAAGDCAYAAADahUEXAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAAsTAAALEwEAmpwYAABbF0lEQVR4nO3dd3gU5drH8e+dQAq9F2kBpKp0FEQELFgQj+21K3ZB7BUb2MWjHsuxe8SuR0HFfhSkiFgQsAMCAipFpAURQkue94/ZhIRskt3NbmY3+/tc11xLZp6dvTPsbO59qjnnEBEREUk0KX4HICIiIhIJJTEiIiKSkJTEiIiISEJSEiMiIiIJSUmMiIiIJCQlMSIiIpKQqvgdQLQ1aNDAZWVl+R2GiIiIRMGcOXPWOucaBjtW6ZKYrKwsZs+e7XcYIiIiEgVm9mtJx9ScJCIiIglJSYyIiIgkJCUxIiIikpCUxIiIiEhCUhIjIiIiCUlJjIiIiCQkJTEiIiKSkJTEiIiISEJSEiMiIiIJSUmMiIiIJCQlMSIiIpKQlMSIiIhIQlISIyIiIglJSYyIiIgkJCUxIiIikpCUxIhIpbF06VKOOeYYGjZsiJlx1llnART5dzjOOusszCy6QUqBDz/8kCpVqrBgwYKCfQ899BD169dnw4YNPkYmiUJJjIjEzIMPPshzzz1XYa931llnMX36dK677jpefPFFLrzwwgp7bQnPzp07ueqqqzjttNPo2LFjwf4LL7yQ9PR0br/9dh+jk0RRxe8ARJJFv7FTWJGdE1LZZnUymTnqoBhHFHsPPvggWVlZEdWChGvbtm3MmDGDiy++mKuvvrrIsZycHFJTU2Meg4Ru/PjxzJ8/n1dffbXI/oyMDIYPH85dd93FjTfeSP369X2KUBKBkhiRCrIiO4dlY4eEVDZr1PsxjqbyWb16Nc456tWrV+xYRkaGDxGFb9OmTdSsWdPvMIKKdmyPPfYYXbp0oWvXrsWOnX766YwZM4bnnnuOq666KmqvKZWPmpNEhGXLlnH88cdTq1YtatWqxT/+8Q+WLl1KVlYWAwcOLFZ+8uTJDB48mDp16pCRkUGXLl144oknipQxM3799VemT5+OmRVsy5YtCyu2t99+m+7du5ORkUGLFi24+eabmTRpEmZW0FR11lln0apVKwBuvfXWgteaNm1aQSy71wa9//77DBgwgAYNGpCZmUnLli057rjjWLhwYbEYNm7cyIgRI2jUqBEZGRn069ePr776qlg55xyPP/44PXv2pFq1atSoUYNBgwYxderUIuWWLVuGmXHLLbfw2muv0bNnTzIzM7nkkktCvi633HILZsbPP//MDTfcQPPmzUlPT6dr16588MEHxcrv3LmTe+65h86dO5ORkUH9+vU59thj+eGHH8KKLf9aTpkyhb59+1KtWjWaN2/OPffcA8CGDRs499xzadSoEdWqVeOoo45i5cqVRV7jjz/+4LPPPuPII48M+ru1adOGDh06MH78+JCvhyQn1cSIJLl169bRv39/Vq9ezfDhw+nUqRMzZsxg0KBBbN68uVj5p556iuHDh9OnTx9uvPFGqlevzqRJkxgxYgS//PIL9957LwAvvvgiV1xxBQ0aNODGG28seH7Dhg1Dju2tt97i+OOPJysri9GjR1OlShWeffZZ3n+/aE3VhRdeSLdu3bjiiis49thjOe644wDo1KlT0PNOnz6do48+mr333pvrr7+eOnXqsHLlSiZPnszixYtp3759kfKHHXYYDRs2ZPTo0axbt45//etfDBkyhKVLlxapnTjjjDN49dVXOeGEEzj77LPZtm0bL7/8MoceeihvvvkmRx99dJHzTpw4kYcffpgRI0YwfPhwatWqFfK1yTds2DCqVq3K1Vdfzfbt23nwwQc55phjWLhwIVlZWQXlTjvtNF5//XUOPfRQRowYwR9//MGjjz5K3759mTFjBt27dw85tm+++YZ3332XCy64gDPPPJPXX3+dUaNGkZGRwfPPP09WVha33HILixcv5uGHH+bMM89k8uTJRa4/wL777lvi79W3b19eeukl/v77b2rUqBH2dZEk4ZyrVFvPnj2dSDxqdd17MSlbXtdcc40D3EsvvRR0/4ABAwr2rVy50qWnp7tTTjml2HkuvfRSl5KS4n755ZeCfa1atSry/HDs3LnTtWjRwtWvX9+tWbOmYH92drZr2bKlA9yzzz5bsH/p0qUOcGPGjCl2LsANGzas4OcrrrjCAW716tWlxjBs2DAHuBEjRhTZ//rrrzvAPfHEEwX73nzzTQe4J598skjZHTt2uJ49e7qsrCyXl5dXJNYqVaq4efPmlXUpghozZowD3JAhQwrO65xzs2bNcoAbNWpUwb6PP/7YAe7EE08sUvbbb791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HpAVQtnTgamhnDcWm5IYkfKZM2eOS01Ndffff39ESczUqVMd4KZOnRrW877++muXnZ1dbP+NN97oAPfvf/87rPNFW25uruvcubPr0aOHy8vLK3Ls7rvvdoCbOXNmyOeL5DrF+zUKJtrXLRLxft3i4RqFo6LjLS2JCak5yTl3t3MuxTm3LISyLznnBoVyXhGJL7m5uZx//vkcfvjhHHfccRX62r169aJ27eLjAk46yVu95Mcffyyyf+vWrdxyyy106NCBatWqUadOHfbZZx+uueaagjLB+i0899xzmBlTpkzhvvvuo23btqSnp9O+fftSV9f+6KOPmDdvHpdeeilmVuRYWloaABs3bgz79w5HuNcIYPv27fzzn/+kW7duVKtWjdq1a9OrVy8eeaRoy//atWsZOXIkLVq0IC0tjRYtWjBy5EjWrSuyFm9I172wRLxu8f7e0v/pLnE1Y6+I+OuBBx5gwYIFvPHGG36HUmD58uUANG7cuMj+kSNHMm7cOM4880yuvPJKdu7cyaJFi5gyZUpI573hhhvIycnhwgsvJD09nccff5yzzjqLPffck379+hUr/9prr5Gamkr//v1Zu3ZtkWOrV68GoGbNmpH8iuVW0jXavn07hx12GNOmTWPw4MGcfvrpZGRk8MMPP/Dmm28W9HfauHEj+++/P4sXL+acc86hR48efPPNNzz++ONMmTKFWbNmFfxu4V73RLxu8fze0v/pbkqqoknUTc1JUiHGHVnyNvelii8fBUuWLHHVqlVzY8eOdc45t3Tp0gptTgpm586drm/fvq5KlSpuwYIFRY7VrVvXHXHEESHF8uyzzxbse/bZZx3gunXr5rZt21awf/ny5S4tLc2dfPLJQc/VsmVLB5S6rVixIuTfLVrXqbRrdM899zjAXX/99cWel5ubW/DvG264wQHu0UcfLVLmkUcecYC76aabCvaFct0Li/Z1i5ZEfW8l4/8ppTQnqSZGRAAYPnw4bdq04corrwz5OXl5eaxfv77Ivvxq5I0bNxb7llavXj1SUkKfY/Pyyy/niy++4K677qJDhw5FjtWuXZuffvqJH3/8kb333jvkc+a76KKLCqq+AZo1a0b79u1ZtGhRsbJr167lt99+49hjj+Wiiy4qdvzEE08kPT2dPfbYI+hrxfI6lXaNXn75ZerWrcvo0aOLPa/w+d966y0aNmzI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"
},
"metadata": {
"needs_background": "light"
}
}
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"We can see that the outputs are consistent with the analytical results."
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"### Calculate the effective quantum dimension\n",
"\n",
"With Paddle Quantum, one can obtain the effective quantum dimension (EQD) by simply using the method `get_eff_qdim()`. For example, the EQD of the hardware-efficient ansatz shown above can be calculated as follows."
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 10,
"source": [
"cir = circuit_hardeff_2qubit()\n",
"qf = QuantumFisher(cir)\n",
"print(cir)\n",
"print(f'The number of parameters is {len(cir.get_param().tolist())}.')\n",
"print(f'The EQD is {qf.get_eff_qdim()}. \\n')"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"--Ry(4.248)----*----Ry(1.233)--\n",
" | \n",
"--Ry(6.121)----x----Ry(4.717)--\n",
" \n",
"The number of parameters is 4.\n",
"The EQD is 3. \n",
"\n"
]
}
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"In this example, the EQD is smaller than the number of parameters, which can be easily seen from the fact that the two $R_y$ gates on the control wire can be merged without changing anything. This inefficiency can be fixed by simply replacing one of the $R_y$ gates with a $R_x$ gate, and then the EQD will increase by one.\n",
"\n",
"If we continue to add gates to the circuit, can we make the EQD grow indefinitely? The answer is clearly no. Provided $n$ qubits, an obvious upper bound can be given by the real number degrees of freedom in a general quantum state, which is equal to $2\\cdot 2^n-2$. The minus two reflect the two constraints of normalization and global phase independence. This can be verified by the following example."
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 11,
"source": [
"def circuit_hardeff_overparam():\n",
" cir = UAnsatz(2)\n",
" theta = 2 * np.pi * np.random.random(8)\n",
" theta = paddle.to_tensor(theta, stop_gradient=False, dtype='float64')\n",
" cir.ry(theta[0], which_qubit=0)\n",
" cir.ry(theta[1], which_qubit=1)\n",
" cir.rx(theta[2], which_qubit=0)\n",
" cir.rx(theta[3], which_qubit=1)\n",
" cir.cnot(control=[0, 1])\n",
" cir.ry(theta[4], which_qubit=0)\n",
" cir.ry(theta[5], which_qubit=1)\n",
" cir.rx(theta[6], which_qubit=0)\n",
" cir.rx(theta[7], which_qubit=1)\n",
"\n",
" return cir\n",
"\n",
"\n",
"cir = circuit_hardeff_overparam()\n",
"qf = QuantumFisher(cir)\n",
"print(cir)\n",
"print(f'The number of parameters is {len(cir.get_param().tolist())}.')\n",
"print(f'The EQD is {qf.get_eff_qdim()}. \\n')"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"--Ry(0.173)----Rx(5.837)----*----Ry(3.082)----Rx(3.997)--\n",
" | \n",
"--Ry(1.354)----Rx(0.536)----x----Ry(5.267)----Rx(5.647)--\n",
" \n",
"The number of parameters is 8.\n",
"The EQD is 6. \n",
"\n"
]
}
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"### Calculate the CFIM and effective dimension\n",
"\n",
"Here we exploit a brief example to show how to calculate the effective dimension defined in Eq.(16) with respect to a quantum neural network with Paddle Quantum.\n",
"\n",
"Firstly, define the encoding method from classical data to quantum data."
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 12,
"source": [
"def U_theta(x, theta, num_qubits, depth, encoding):\n",
" cir = UAnsatz(num_qubits)\n",
" if encoding == 'IQP':\n",
" S = [[i, i + 1] for i in range(num_qubits - 1)]\n",
" cir.iqp_encoding(x, num_repeats=1, pattern=S)\n",
" cir.complex_entangled_layer(theta, depth)\n",
" elif encoding == 're-uploading':\n",
" for i in range(depth):\n",
" cir.complex_entangled_layer(theta[i:i + 1], depth=1)\n",
" for j in range(num_qubits):\n",
" cir.rx(x[j], which_qubit=j)\n",
" cir.complex_entangled_layer(theta[-1:], depth=1)\n",
" else:\n",
" raise RuntimeError('Non-existent encoding method')\n",
" return cir"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"Then, define our quantum neural network along with the loss function using PaddlePaddle."
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 13,
"source": [
"import paddle.nn as nn\n",
"\n",
"class QuantumNeuralNetwork(nn.Layer):\n",
" def __init__(self, num_qubits, depth, encoding):\n",
" super().__init__()\n",
" self.num_qubits, self.depth, self.encoding = num_qubits, depth, encoding\n",
" if self.encoding == 'IQP':\n",
" self.theta = self.create_parameter(\n",
" shape=[self.depth, self.num_qubits, 3],\n",
" default_initializer=paddle.nn.initializer.Uniform(low=0.0,\n",
" high=2 *\n",
" np.pi),\n",
" dtype='float64',\n",
" is_bias=False)\n",
" elif self.encoding == 're-uploading':\n",
" self.theta = self.create_parameter(\n",
" shape=[self.depth + 1, self.num_qubits, 3],\n",
" default_initializer=paddle.nn.initializer.Uniform(low=0.0,\n",
" high=2 *\n",
" np.pi),\n",
" dtype='float64',\n",
" is_bias=False)\n",
" else:\n",
" raise RuntimeError('Non-existent encoding method')\n",
"\n",
" def forward(self, x):\n",
" if not paddle.is_tensor(x):\n",
" x = paddle.to_tensor(x)\n",
" cir = U_theta(x, self.theta, self.num_qubits, self.depth,\n",
" self.encoding)\n",
" cir.run_state_vector()\n",
" return cir.expecval([[1.0, 'z0']]) * paddle.to_tensor(\n",
" [0.5], dtype='float64') + paddle.to_tensor([0.5], dtype='float64')"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"Finally, define a CFIM calculator and calculate the effective dimension corresponding to different size of training samples."
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 17,
"source": [
"# Configure model parameters\n",
"num_qubits = 4\n",
"depth = 2\n",
"num_inputs = 100\n",
"num_thetas = 10\n",
"# Define the CFIM calculator\n",
"cfim = ClassicalFisher(model=QuantumNeuralNetwork,\n",
" num_thetas=num_thetas,\n",
" num_inputs=num_inputs,\n",
" num_qubits=num_qubits,\n",
" depth=depth,\n",
" encoding='IQP')\n",
"# Compute the normalized classical Fisher information\n",
"fim, _ = cfim.get_normalized_cfisher()\n",
"# Compute the effective dimension for different size of samples\n",
"n = [5000, 8000, 10000, 40000, 60000, 100000, 150000, 200000, 500000, 1000000]\n",
"effdim = cfim.get_eff_dim(fim, n)"
],
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"running in get_gradient: 100%|##################################| 1000/1000 [02:05<00:00, 7.94it/s]\n"
]
}
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"Plot the ratio of the effective dimension over number of parameters vs. sample size."
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 19,
"source": [
"fig = plt.figure(figsize=(9, 6))\n",
"ax = fig.add_subplot(111)\n",
"print('the number of parameters:%s' % cfim.num_params)\n",
"ax.plot(n, np.array(effdim) / cfim.num_params)\n",
"label_font_size = 14\n",
"ax.set_xlabel('sample size', fontsize=label_font_size)\n",
"ax.set_ylabel('effective dimension / number of parameters', fontsize=label_font_size)\n",
"ax.tick_params(labelsize=label_font_size)"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"the number of parameters:24\n"
]
},
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 648x432 with 1 Axes>"
],
"image/png": "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"
},
"metadata": {
"needs_background": "light"
}
}
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"## Conclusion\n",
"\n",
"This tutorial briefly introduces the concept of classical and quantum Fisher information and their relationship from a geometric point of view. Then, we illustrates their applications in quantum machine learning by taking effective dimension as an example. Finally, we show how to actually perform calculations of these quantities with Paddle Quantum."
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"_______\n",
"\n",
"## References\n",
"\n",
"[1] Meyer, Johannes Jakob. \"Fisher information in noisy intermediate-scale quantum applications.\" [arXiv preprint arXiv:2103.15191 (2021).](https://arxiv.org/abs/2103.15191)\n",
"\n",
"[2] Haug, Tobias, Kishor Bharti, and M. S. Kim. \"Capacity and quantum geometry of parametrized quantum circuits.\" [arXiv preprint arXiv:2102.01659 (2021).](https://arxiv.org/abs/2102.01659)\n",
"\n",
"[3] Stokes, James, et al. \"Quantum natural gradient.\" [Quantum 4 (2020): 269.](https://quantum-journal.org/papers/q-2020-05-25-269/)\n",
"\n",
"[4] Mari, Andrea, Thomas R. Bromley, and Nathan Killoran. \"Estimating the gradient and higher-order derivatives on quantum hardware.\" [Physical Review A 103.1 (2021): 012405.](https://journals.aps.org/pra/abstract/10.1103/PhysRevA.103.012405)\n",
"\n",
"[5] Datta, Nilanjana, and Felix Leditzky. \"A limit of the quantum Rényi divergence.\" [Journal of Physics A: Mathematical and Theoretical 47.4 (2014): 045304.](https://iopscience.iop.org/article/10.1088/1751-8113/47/4/045304)\n",
"\n",
"[6] Abbas, Amira, et al. \"The power of quantum neural networks.\" [Nature Computational Science 1.6 (2021): 403-409.](https://www.nature.com/articles/s43588-021-00084-1)"
],
"metadata": {}
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
\ No newline at end of file
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
"cells": [ "cells": [
{ {
"cell_type": "markdown", "cell_type": "markdown",
"id": "dedicated-alexander",
"metadata": {}, "metadata": {},
"source": [ "source": [
"# 在 Paddle Quantum 中模拟含噪量子电路\n", "# 在 Paddle Quantum 中模拟含噪量子电路\n",
...@@ -11,6 +12,7 @@ ...@@ -11,6 +12,7 @@
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"id": "weird-functionality",
"metadata": {}, "metadata": {},
"source": [ "source": [
"## 噪声简介\n", "## 噪声简介\n",
...@@ -54,7 +56,7 @@ ...@@ -54,7 +56,7 @@
"\\tag{4}\n", "\\tag{4}\n",
"$$\n", "$$\n",
"\n", "\n",
"其中 $X,I$ 是泡利矩阵。 对应的 *Kruas* 算符为:\n", "其中 $X,I$ 是泡利矩阵。 对应的 *Kraus* 算符为:\n",
"\n", "\n",
"$$\n", "$$\n",
"E_0 = \\sqrt{1-p}\n", "E_0 = \\sqrt{1-p}\n",
...@@ -77,6 +79,7 @@ ...@@ -77,6 +79,7 @@
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"id": "transsexual-hayes",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Paddle Quantum 中添加信道的方式\n", "### Paddle Quantum 中添加信道的方式\n",
...@@ -87,6 +90,7 @@ ...@@ -87,6 +90,7 @@
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 1, "execution_count": 1,
"id": "scheduled-attraction",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-08T05:16:08.247239Z", "end_time": "2021-04-08T05:16:08.247239Z",
...@@ -136,6 +140,7 @@ ...@@ -136,6 +140,7 @@
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"id": "indian-slave",
"metadata": {}, "metadata": {},
"source": [ "source": [
"之后,我们加上一个 $p=0.1$ 的比特反转噪声,并测量通过信道之后的量子比特。 \n", "之后,我们加上一个 $p=0.1$ 的比特反转噪声,并测量通过信道之后的量子比特。 \n",
...@@ -145,6 +150,7 @@ ...@@ -145,6 +150,7 @@
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 2, "execution_count": 2,
"id": "fiscal-literature",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-08T05:16:09.221527Z", "end_time": "2021-04-08T05:16:09.221527Z",
...@@ -193,6 +199,7 @@ ...@@ -193,6 +199,7 @@
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"id": "bibliographic-undergraduate",
"metadata": {}, "metadata": {},
"source": [ "source": [
"可以看到,经过了比特反转信道(概率为 $p=0.1$)之后的量子态变成了混合态 $0.9 | 0 \\rangle \\langle 0 | + 0.1 | 1 \\rangle \\langle 1 |$。\n", "可以看到,经过了比特反转信道(概率为 $p=0.1$)之后的量子态变成了混合态 $0.9 | 0 \\rangle \\langle 0 | + 0.1 | 1 \\rangle \\langle 1 |$。\n",
...@@ -201,6 +208,7 @@ ...@@ -201,6 +208,7 @@
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"id": "million-diagnosis",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### 常用噪声信道\n", "### 常用噪声信道\n",
...@@ -307,6 +315,7 @@ ...@@ -307,6 +315,7 @@
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"id": "alert-senator",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### 自定义信道\n", "### 自定义信道\n",
...@@ -317,6 +326,7 @@ ...@@ -317,6 +326,7 @@
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 3, "execution_count": 3,
"id": "mobile-death",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-08T05:17:30.681411Z", "end_time": "2021-04-08T05:17:30.681411Z",
...@@ -375,6 +385,7 @@ ...@@ -375,6 +385,7 @@
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"id": "proper-director",
"metadata": {}, "metadata": {},
"source": [ "source": [
"按照上述例子,用户可以通过自定义 *Kraus* 算符的方式实现特定的信道。" "按照上述例子,用户可以通过自定义 *Kraus* 算符的方式实现特定的信道。"
...@@ -382,6 +393,7 @@ ...@@ -382,6 +393,7 @@
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"id": "tested-elder",
"metadata": {}, "metadata": {},
"source": [ "source": [
"## 拓展:Paddle Quantum 模拟含噪纠缠资源\n", "## 拓展:Paddle Quantum 模拟含噪纠缠资源\n",
...@@ -393,6 +405,7 @@ ...@@ -393,6 +405,7 @@
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 4, "execution_count": 4,
"id": "spread-monkey",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-08T05:24:35.552425Z", "end_time": "2021-04-08T05:24:35.552425Z",
...@@ -450,6 +463,7 @@ ...@@ -450,6 +463,7 @@
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"id": "comparable-athletics",
"metadata": {}, "metadata": {},
"source": [ "source": [
"**注释:** 在 [纠缠蒸馏](../locc/EntanglementDistillation_LOCCNET_CN.ipynb) 的教程中我们介绍了如何利用 Paddle Quantm 中的 LoccNet 模块来研究纠缠蒸馏,即利用多个含噪声的纠缠对来提取高保真度的纠缠对,感兴趣的读者可以前往阅读。" "**注释:** 在 [纠缠蒸馏](../locc/EntanglementDistillation_LOCCNET_CN.ipynb) 的教程中我们介绍了如何利用 Paddle Quantm 中的 LoccNet 模块来研究纠缠蒸馏,即利用多个含噪声的纠缠对来提取高保真度的纠缠对,感兴趣的读者可以前往阅读。"
...@@ -457,6 +471,7 @@ ...@@ -457,6 +471,7 @@
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"id": "elegant-bikini",
"metadata": {}, "metadata": {},
"source": [ "source": [
"## 应用: Paddle Quantum 模拟含噪变分量子本征求解器(VQE)\n", "## 应用: Paddle Quantum 模拟含噪变分量子本征求解器(VQE)\n",
...@@ -477,6 +492,7 @@ ...@@ -477,6 +492,7 @@
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 5, "execution_count": 5,
"id": "unavailable-october",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-08T05:34:47.301281Z", "end_time": "2021-04-08T05:34:47.301281Z",
...@@ -508,6 +524,7 @@ ...@@ -508,6 +524,7 @@
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 6, "execution_count": 6,
"id": "protected-difficulty",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-08T05:34:51.742273Z", "end_time": "2021-04-08T05:34:51.742273Z",
...@@ -666,6 +683,7 @@ ...@@ -666,6 +683,7 @@
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"id": "important-testing",
"metadata": {}, "metadata": {},
"source": [ "source": [
"可以看到,含噪的变分量子本征求解器的效果要差于不含噪的版本,无法达到化学精度的要求 $\\varepsilon = 0.0016$ Ha。" "可以看到,含噪的变分量子本征求解器的效果要差于不含噪的版本,无法达到化学精度的要求 $\\varepsilon = 0.0016$ Ha。"
...@@ -673,6 +691,7 @@ ...@@ -673,6 +691,7 @@
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"id": "extensive-forge",
"metadata": {}, "metadata": {},
"source": [ "source": [
"## 总结\n", "## 总结\n",
...@@ -682,6 +701,7 @@ ...@@ -682,6 +701,7 @@
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"id": "inappropriate-board",
"metadata": {}, "metadata": {},
"source": [ "source": [
"---\n", "---\n",
...@@ -716,7 +736,7 @@ ...@@ -716,7 +736,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.8.3" "version": "3.7.10"
}, },
"toc": { "toc": {
"base_numbering": 1, "base_numbering": 1,
......
{
"cells": [
{
"cell_type": "markdown",
"id": "c1a5f1e6",
"metadata": {},
"source": [
"# 基于施密特分解的分布式变分量子本征求解器\n",
"\n",
"*Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.*"
]
},
{
"cell_type": "markdown",
"id": "cf44390c",
"metadata": {
"tags": []
},
"source": [
"## 概览\n",
"\n",
"在物理和化学等学科中,一个非常重要的问题就是提取分子、原子等物理系统的基态信息。系统的基态是由系统对应的哈密顿量决定的。目前普遍认为量子计算机在求解哈密顿量基态问题上具有优势。[变分量子本征求解器](https://qml.baidu.com/tutorials/quantum-simulation/variational-quantum-eigensolver.html)(variational quantum eigensolver, VQE),作为有望在近期展现量子优势的算法之一,为研究者们提供了可以在含噪的中等规模量子(NISQ)设备上研究量子化学的可能。然而,目前 NISQ 设备仍存在许多局限性,阻碍了大规模量子算法的运行。例如,受限于现有量子设备所能提供的量子比特数,研究者们无法利用 VQE 在 NISQ 设备上模拟真实的大分子。为了突破这一限制,许多分布式方案 [1-3] 相继被提出。\n",
"在本教程中,我们以 [4] 提出的基于施密特分解的 VQE 为例,向读者展示如何利用 Paddle Quantum 实现分布式量子算法。"
]
},
{
"cell_type": "markdown",
"id": "f3fcc1b4",
"metadata": {},
"source": [
"## 施密特分解\n",
"\n",
"对于任意处于复合系统 $AB$ 上的纯态 $|\\psi\\rangle$,我们有如下平凡分解:\n",
"\n",
"$$\n",
"|\\psi\\rangle=\\sum_{ij}a_{ij}|i\\rangle\\otimes|j\\rangle,\n",
"\\tag{1}\n",
"$$\n",
"\n",
"其中 $|i\\rangle$ 和 $|j\\rangle$ 分别是子系统 $A$、$B$ 上的计算基底,$a_{ij}$ 是某复矩阵 $a$ 的元素。接下来,我们对矩阵 $a$ 运用[奇异值分解](https://zh.wikipedia.org/wiki/奇异值分解)(singular value decomposition, SVD),即,$a = udv$,其中 $u,v$ 是酉矩阵,$d$ 是对角矩阵。那么,$a_{ij}=\\sum_ku_{ik}d_{kk}v_{kj}$。\n",
"\n",
"通过定义 \n",
"\n",
"$$\n",
"\\begin{aligned}\n",
"|k_A\\rangle\\equiv & \\sum_iu_{ik}|i\\rangle=u|k\\rangle,\\\\\n",
"|k_B\\rangle\\equiv & \\sum_jv_{kj}|j\\rangle=v^T|k\\rangle,\\\\\n",
"\\lambda_k\\equiv & d_{kk},\\end{aligned}\n",
"\\tag{2}\n",
"$$\n",
"\n",
"我们可以把(1)式重写为\n",
"\n",
"$$\n",
"\\begin{aligned}\n",
" |\\psi\\rangle &= \\sum_{ijk}u_{ik}d_{kk}v_{kj}|i\\rangle\\otimes|j\\rangle \\\\\n",
" &= \\sum_{k}\\lambda_{k}\\Big(\\sum_iu_{ik}|i\\rangle\\Big)\\otimes\\Big(\\sum_jv_{kj}|j\\rangle\\Big) \\\\\n",
" &=\\sum_{k}\\lambda_k(u|k\\rangle\\otimes v^T|k\\rangle)\\\\\n",
" &=\\sum_{k}\\lambda_k|k_A\\rangle\\otimes|k_B\\rangle.\n",
"\\end{aligned}\n",
"\\tag{3}\n",
"$$\n",
"\n",
"形如 $|\\psi\\rangle=\\sum_k\\lambda_k|k_A\\rangle\\otimes|k_B\\rangle$ 的分解方式就称为 **施密特分解** [5]。同时,$\\{\\lambda_k\\}_k$ 被称作施密特系数,非零 $\\lambda_k$ 的数量被称为 $|\\psi\\rangle$ 的施密特秩。事实上,奇异值分解的性质还保证了 $\\lambda_k\\in\\mathbb{R}^+$ 及 $\\sum_k\\lambda_k^2=1$。"
]
},
{
"cell_type": "markdown",
"id": "620e053c",
"metadata": {
"tags": []
},
"source": [
"## 基于施密特分解的分布式 VQE\n",
"\n",
"作为标准 VQE [6] 的一个变种,分布式 VQE 同样试图寻找一个 $N$ 量子比特哈密顿量 $\\hat{H}=\\sum_tc_t\\hat{H}_t^{(A)}\\otimes\\hat{H}_t^{(B)}$ 的基态及其能量,其中 $\\hat{H}_t^{(A)},\\hat{H}_t^{(B)}$ 是分别作用于子系统 $A$、$B$ 上的哈密顿量分量(我们假设 $A$、$B$ 都包含 $N/2$ 量子比特)。\n",
"\n",
"我们从如下试探波函数开始:\n",
"\n",
"$$\n",
"|\\psi\\rangle\\equiv\\sum_{k=1}^S\\lambda_k\\Big(U(\\boldsymbol{\\theta})|k\\rangle\\Big)\\otimes\\Big(V(\\boldsymbol{\\phi})|k\\rangle\\Big)\n",
"\\tag{4},\n",
"$$\n",
"\n",
"其中 $\\boldsymbol{\\lambda}\\equiv(\\lambda_1, \\lambda_2,...,\\lambda_S)^T$,$1\\leq S\\leq 2^{N/2}$ 是一个用户定义的常数。根据施密特分解,目标基态同样可写成(4)式的形式。因此,通过寻找合适的参数向量 $\\boldsymbol{\\lambda}, \\boldsymbol{\\theta}$ 和 $\\boldsymbol{\\phi}$,我们可以在任意误差内近似目标基态。\n",
"\n",
"接下来,对于所有 $i,j=1,...,S$,我们在一台 $N/2$ 量子比特的量子计算机上计算如下项:\n",
"\n",
"$$\n",
"\\begin{aligned}\n",
"E_{ijt}^A(\\boldsymbol{\\theta}) &\\equiv \\langle i|U^\\dagger(\\boldsymbol{\\theta}) \\hat{H}_t^{(A)} U(\\boldsymbol{\\theta})|j\\rangle,\\\\\n",
"E_{ijt}^B(\\boldsymbol{\\phi}) &\\equiv \\langle i|V^\\dagger(\\boldsymbol{\\phi}) \\hat{H}_t^{(B)} V(\\boldsymbol{\\phi}))|j\\rangle.\n",
"\\end{aligned}\n",
"\\tag{5}\n",
"$$\n",
"\n",
"然后,在一台经典计算机上,我们根据如下定义构造一个 $S\\times S$ 维的矩阵 $M(\\boldsymbol{\\theta},\\boldsymbol{\\phi})$:\n",
"\n",
"$$\n",
"[M(\\boldsymbol{\\theta},\\boldsymbol{\\phi})]_{ij}\\equiv\\sum_tc_tE_{ijt}^A(\\boldsymbol{\\theta})E_{ijt}^B(\\boldsymbol{\\phi}).\n",
"\\tag{6}\n",
"$$\n",
"\n",
"这样,目标基态能量就可以写为 \n",
"\n",
"$$\n",
"\\begin{aligned}\n",
"E_{tar} &= \\min_{\\boldsymbol{\\lambda}, \\boldsymbol{\\theta}, \\boldsymbol{\\phi}} \\langle{\\psi}|\\hat{H}|\\psi\\rangle \\\\\n",
" &= \\min_{\\boldsymbol{\\lambda}, \\boldsymbol{\\theta}, \\boldsymbol{\\phi}}\\Big(\\sum_{i,j=1}^S\\lambda_i\\lambda_j[M(\\boldsymbol{\\theta},\\boldsymbol{\\phi})]_{ij}\\Big)\\\\\n",
" &= \\min_{\\boldsymbol{\\theta}, \\boldsymbol{\\phi}} E(\\boldsymbol{\\theta},\\boldsymbol{\\phi}),\n",
"\\end{aligned}\n",
"\\tag{7}\n",
"$$\n",
"\n",
"其中 $E(\\boldsymbol{\\theta},\\boldsymbol{\\phi})\\equiv\\min_{\\boldsymbol{\\lambda}} \\boldsymbol{\\lambda}^T M(\\boldsymbol{\\theta},\\boldsymbol{\\phi})\\boldsymbol{\\lambda}$。根据线性代数的内容,不难发现,$E(\\boldsymbol{\\theta},\\boldsymbol{\\phi})$ 正是矩阵 $M(\\boldsymbol{\\theta},\\boldsymbol{\\phi})$ 的最小特征值,可以通过经典算法求得。\n",
"\n",
"最终,我们重复如上过程,并使用基于梯度下降的优化方法最小化 $E(\\boldsymbol{\\theta},\\boldsymbol{\\phi})$,使其趋近于 $E_{tar}$。\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "f79d3333",
"metadata": {
"tags": []
},
"source": [
"## 量桨实现\n",
"\n",
"首先,我们导入必要的包。由于我们要使用飞桨和量桨的最新功能,请确保您的 *PaddlePaddle* >= 2.2.0 且 *Paddle Quantum* >= 2.1.3。"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "bb7c0db4",
"metadata": {},
"outputs": [],
"source": [
"import time\n",
"import numpy as np\n",
"from matplotlib import pyplot as plt\n",
"\n",
"import paddle\n",
"from paddle_quantum.circuit import UAnsatz\n",
"from paddle_quantum.utils import pauli_str_to_matrix, schmidt_decompose"
]
},
{
"cell_type": "markdown",
"id": "c84dd264",
"metadata": {},
"source": [
"定义一些全局常数:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "27e4ce36",
"metadata": {},
"outputs": [],
"source": [
"N = 10 # 量子比特数\n",
"SEED = 16 # 固定随机种子\n",
"ITR = 100 # 设置迭代次数\n",
"LR = 0.1 # 设置学习率\n",
"D = 3 # 设置量子神经网络的层数"
]
},
{
"cell_type": "markdown",
"id": "3db38f56",
"metadata": {},
"source": [
"下面这一函数经典地计算出哈密顿量 $H$ 的基态信息(基态对能量和施密特秩),以作为后面量子模型的基准参照。"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "32b310ed",
"metadata": {},
"outputs": [],
"source": [
"def get_ground_state_info(H):\n",
"\n",
" # 计算 H 的特征值与特征向量\n",
" vals, vecs = paddle.linalg.eigh(H)\n",
" # 获取基态\n",
" ground_state = vecs[:, 0].numpy()\n",
" # 获取基态能量\n",
" ground_state_energy = vals.tolist()[0]\n",
" print(f'The ground state energy is {ground_state_energy:.5f} Ha.')\n",
" # 对基态运用施密特分解\n",
" l, _, _ = schmidt_decompose(ground_state)\n",
" print(f'Schmidt rank of the ground state is {l.size}.')\n",
"\n",
" return ground_state_energy"
]
},
{
"cell_type": "markdown",
"id": "8c2c88d3",
"metadata": {},
"source": [
"现在,我们生成一个哈密顿量并计算其基态信息。"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "6149b4d4",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The ground state energy is -0.99783 Ha.\n",
"Schmidt rank of the ground state is 3.\n"
]
}
],
"source": [
"# 固定随机种子\n",
"np.random.seed(SEED)\n",
"\n",
"# 硬编码一个哈密顿量\n",
"coefs = [-0.8886258, 0.453882]\n",
"pauli_str = ['x0,z1,z2,z4,x5,y6,y7,x8,x9', 'y0,x1,x2,x3,y4,x5,z6,z7,y8,x9']\n",
"pauli_str_A = ['x0,z1,z2,z4', 'y0,x1,x2,x3,y4'] # 子系统 A 的泡利字符串\n",
"pauli_str_B = ['x0,y1,y2,x3,x4', 'x0,z1,z2,y3,x4'] # 子系统 B 的泡利字符串\n",
"\n",
"# 把相关对象转换为张量形式\n",
"H_mtr = paddle.to_tensor(pauli_str_to_matrix(zip(coefs, pauli_str), n=N))\n",
"coefs = paddle.to_tensor(coefs)\n",
"H_A = [pauli_str_to_matrix([[1., pstr]], n=N//2) for pstr in pauli_str_A]\n",
"H_A = paddle.to_tensor(np.stack(H_A))\n",
"H_B = [pauli_str_to_matrix([[1., pstr]], n=N-N//2) for pstr in pauli_str_B]\n",
"H_B = paddle.to_tensor(np.stack(H_B))\n",
"\n",
"# 计算该哈密顿量的基态信息\n",
"ground_state_energy = get_ground_state_info(H_mtr)"
]
},
{
"cell_type": "markdown",
"id": "9abf331c",
"metadata": {},
"source": [
"准备好一个哈密顿量后,我们可以构建一个分布式 VQE 来求解它。"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "32cacc67",
"metadata": {},
"outputs": [],
"source": [
"# 构造参数化量子电路\n",
"def U_theta(param, N, D):\n",
" \n",
" cir = UAnsatz(N) # 初始化一个宽度为 N 量子比特的电路\n",
" cir.complex_entangled_layer(param, D) # 添加量子门\n",
" return cir.U # 获取参数化电路的矩阵\n",
"\n",
"# 把参数化电路作用在计算基底上\n",
"# 并返回一个形状为 [2**N, num_states] 的张量\n",
"def output_states(theta, num_states, N, D):\n",
" # 创建 num_states 个计算基底\n",
" basis = paddle.eye(2**N, num_states)\n",
" \n",
" # 获得参数化电路\n",
" U = U_theta(theta, N, D)\n",
" \n",
" # 把参数化电路作用在这些基底上\n",
" vec = U @ basis \n",
" \n",
" return vec"
]
},
{
"cell_type": "markdown",
"id": "0ca5787c",
"metadata": {},
"source": [
"以下代码是本教程的核心。请读者仔细阅读,并与前文的公式叙述做比较。"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "6ebf5159",
"metadata": {},
"outputs": [],
"source": [
"# 构造分布式模型\n",
"class DistributedVQE(paddle.nn.Layer):\n",
" def __init__(self, N, D, S):\n",
" super().__init__()\n",
" paddle.seed(SEED)\n",
"\n",
" # 定义常数 S\n",
" self.S = S\n",
" self.N, self.D = N, D\n",
" # 初始化参数列表 theta, phi,并用 [0, 2*pi] 的均匀分布来填充初始值\n",
" self.theta = self.create_parameter(shape=[D, N//2, 3], dtype=\"float64\",\n",
" default_initializer=paddle.nn.initializer.Uniform(low=0.0, high=2*np.pi))\n",
" self.phi = self.create_parameter(shape=[D, N - N//2, 3], dtype=\"float64\",\n",
" default_initializer=paddle.nn.initializer.Uniform(low=0.0, high=2*np.pi))\n",
" \n",
" # 分布式 VQE 的核心逻辑\n",
" def forward(self):\n",
" # 分别获得子系统 A、B 上的 U|k> 和 V|k> \n",
" vec_A = output_states(self.theta, self.S, self.N//2, self.D)\n",
" vec_B = output_states(self.phi, self.S, self.N - self.N//2, self.D)\n",
" \n",
" # 计算由前文定义的 E_{ijt}^A 和 E_{ijt}^B 组成的张量 E_A, E_B\n",
" E_A = vec_A.conj().t() @ H_A @ vec_A\n",
" E_B = vec_B.conj().t() @ H_B @ vec_B\n",
" M = (coefs.reshape([-1, 1, 1]) * E_A * E_B).sum(0)\n",
"\n",
" # 计算矩阵 M 的最小特征值\n",
" eigval = paddle.linalg.eigvalsh(M)\n",
" loss = eigval[0]\n",
" \n",
" return loss"
]
},
{
"cell_type": "markdown",
"id": "d04669ff",
"metadata": {},
"source": [
"定义训练函数。"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "066f5e72",
"metadata": {},
"outputs": [],
"source": [
"def train(model):\n",
" start_time = time.time() # 用以计算该函数的运行时长\n",
" \n",
" # 我们使用基于梯度下降的优化器 Adam 来优化 theta 和 phi\n",
" opt = paddle.optimizer.Adam(learning_rate=LR, parameters=model.parameters())\n",
" summary_loss = [] # 记录损失历史\n",
"\n",
" # 迭代优化\n",
" for itr in range(ITR):\n",
"\n",
" # 前向传播,计算损失函数\n",
" loss = model()\n",
"\n",
" # 后向传播,优化损失函数\n",
" loss.backward()\n",
" opt.minimize(loss)\n",
" opt.clear_grad()\n",
"\n",
" # 更新优化结果\n",
" summary_loss.append(loss.numpy())\n",
"\n",
" # 打印中间结果\n",
" if (itr+1) % 20 == 0:\n",
" print(f\"iter: {itr+1}, loss: {loss.tolist()[0]: .4f} Ha\")\n",
"\n",
" print(f'Ground truth is {ground_state_energy:.4f} Ha')\n",
" print(f'Training took {time.time() - start_time:.2f}s')\n",
" \n",
" plt.plot(list(range(ITR)), summary_loss, color='r', label='loss')\n",
" plt.hlines(y=ground_state_energy, xmin=0, xmax=ITR, linestyle=':', label='ground truth')\n",
" plt.legend()\n",
" plt.title(f'Loss for {type(model).__name__} on a {N}-qubit Hamiltonian')\n",
" plt.show()"
]
},
{
"cell_type": "markdown",
"id": "c8770b19",
"metadata": {},
"source": [
"现在,我们实例化并训练分布式模型。"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "78b46dcc",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"iter: 20, loss: -0.9244 Ha\n",
"iter: 40, loss: -0.9906 Ha\n",
"iter: 60, loss: -0.9968 Ha\n",
"iter: 80, loss: -0.9977 Ha\n",
"iter: 100, loss: -0.9978 Ha\n",
"Ground truth is -0.9978 Ha\n",
"Training took 13.01s\n"
]
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# 注意,由于我们构造的哈密顿量在两子系统间相互作用较小,我们只需设置 S = 4.\n",
"#(更多解释请见总结部分)\n",
"vqe = DistributedVQE(N, D, S=4)\n",
"train(vqe)"
]
},
{
"cell_type": "markdown",
"id": "9eb85055",
"metadata": {},
"source": [
"在上图中,我们用虚线画出了真实的基态能量。可以看到,loss 曲线收敛至虚线,表明我们的分布式 VQE 成功找到了该哈密顿量的基态能量。然而,要妥当地评估我们的模型,我们还需将它与标准 VQE 做比较。因此,下面我们构建标准 VQE 模型:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "2fff9166",
"metadata": {},
"outputs": [],
"source": [
"class StandardVQE(paddle.nn.Layer):\n",
" def __init__(self, N, D):\n",
" super().__init__()\n",
" paddle.seed(SEED)\n",
" self.N, self.D = N, D\n",
" self.theta = self.create_parameter(shape=[D, N, 3], dtype=\"float64\",\n",
" default_initializer=paddle.nn.initializer.Uniform(low=0.0, high=2*np.pi))\n",
" \n",
" def forward(self):\n",
" vec = output_states(self.theta, 1, self.N, self.D)\n",
" loss = vec.conj().t() @ H_mtr @ vec\n",
" return loss.cast('float64').flatten()"
]
},
{
"cell_type": "markdown",
"id": "8bc5dcfd",
"metadata": {},
"source": [
"实例化并训练标准 VQE。"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "a35f3eb4",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"iter: 20, loss: -0.8365 Ha\n",
"iter: 40, loss: -0.9852 Ha\n",
"iter: 60, loss: -0.9958 Ha\n",
"iter: 80, loss: -0.9975 Ha\n",
"iter: 100, loss: -0.9978 Ha\n",
"Ground truth is -0.9978 Ha\n",
"Training took 721.76s\n"
]
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"svqe = StandardVQE(N, D)\n",
"train(svqe) # 训练标准 VQE"
]
},
{
"cell_type": "markdown",
"id": "5688a618",
"metadata": {},
"source": [
"有趣的是,通过比较两个模型的运行时间,我们发现,分布式 VQE 的运行速度比标准 VQE 快了五十多倍!事实上,这很容易理解:在分布式模型中,我们只需模拟两个 $N/2$ 量子比特的酉变换,这无论在时间还是空间上,都比标准 VQE 中模拟一个 $N$ 量子比特的酉变换高效得多。"
]
},
{
"cell_type": "markdown",
"id": "94cda668",
"metadata": {
"tags": []
},
"source": [
"## 总结\n",
"\n",
"在此教程中,我们构造了一个分布式 VQE 并展示了其部分优势:\n",
"- NISQ 设备的计算范围得以拓展。通过分布式策略,我们可以运行超过硬件量子比特数的量子算法。\n",
"- 计算效率得到提升。对于量子过程的经典模拟而言,分布式算法降低了酉矩阵的维度,因此降低了模拟这些矩阵所需的时间、空间消耗。\n",
"\n",
"同时,需要注意的是,用户定义的常数 $S$ 在训练准确度和效率上扮演了重要角色:\n",
"- 对于子系统间相互作用弱的哈密顿量而言,其基态在子系统间纠缠较弱 [7]。因此,其施密特秩较低,可以被一个较小的 $S$ 精确且高效地模拟。事实上,我们所给的演示及大多数物理、化学中有意义的哈密顿量都具有此性质。\n",
"- 相反的,对于子系统间相互作用强的哈密顿量而言,其基态在子系统间纠缠较强,因此需要一个较大的 $S$ 来模拟。但是,无论如何,$S$ 的上界是 $2^{N/2}$,因此矩阵 $M$ 的维度上界是 $2^{N/2}\\times2^{N/2}$,这仍然比初始哈密顿量的维度($2^{N}\\times 2^{N}$)小。因此,该算法的效率总是优于纯经典模拟。"
]
},
{
"cell_type": "markdown",
"id": "922679aa",
"metadata": {
"jp-MarkdownHeadingCollapsed": true,
"tags": []
},
"source": [
"_______\n",
"\n",
"# 参考文献\n",
"\n",
"[1] Fujii, Keisuke, et al. \"Deep Variational Quantum Eigensolver: a divide-and-conquer method for solving a larger problem with smaller size quantum computers.\" [arXiv preprint arXiv:2007.10917 (2020)](https://arxiv.org/abs/2007.10917).\n",
"\n",
"[2] Zhang, Yu, et al. \"Variational Quantum Eigensolver with Reduced Circuit Complexity.\" [arXiv preprint arXiv:2106.07619 (2021)](https://arxiv.org/abs/2106.07619).\n",
"\n",
"[3] Peng, Tianyi et al. \"Simulating Large Quantum Circuits On A Small Quantum Computer\". [Physical Review Letters 125.15, (2020): 150504](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.125.150504).\n",
"\n",
"[4] Eddins, Andrew, et al. \"Doubling the size of quantum simulators by entanglement forging.\" [arXiv preprint arXiv:2104.10220 (2021)](https://arxiv.org/abs/2104.10220).\n",
"\n",
"[5] Nielsen, Michael A., and Isaac L. Chuang. Quantum Computation and Quantum Information. Cambridge University Press, 2010.\n",
"\n",
"[6] Moll, Nikolaj, et al. \"Quantum optimization using variational algorithms on near-term quantum devices.\" [Quantum Science and Technology 3.3 (2018): 030503](https://iopscience.iop.org/article/10.1088/2058-9565/aab822).\n",
"\n",
"[7] Khatri, Sumeet, and Mark M. Wilde. \"Principles of quantum communication theory: A modern approach.\" [arXiv preprint arXiv:2011.04672 (2020)](https://arxiv.org/abs/2011.04672)."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
{
"cells": [
{
"cell_type": "markdown",
"id": "responsible-handle",
"metadata": {},
"source": [
"# Distributed Variational Quantum Eigensolver Based on Schmidt Decomposition\n",
"*Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.*"
]
},
{
"cell_type": "markdown",
"id": "superb-sunrise",
"metadata": {
"tags": []
},
"source": [
"## Overview\n",
"\n",
"Retrieving ground state information of a Hamiltonian in amongst the essential questions in physics and chemistry. Currently, it is widely believed that quantum computers are advantageous in solving this kind of problem. As one of the promising algorithms to demonstrate quantum supremacy in the near term, [Variational Quantum Eigensolver (VQE)](https://qml.baidu.com/tutorials/quantum-simulation/variational-quantum-eigensolver.html)\n",
"enables the study of quantum chemistry on Noisy Intermediate-Scale Quantum (NISQ) devices. However, various technical limitations still exist on current NISQ hardware, forbidding the deployment of large-scale quantum algorithms. For example, limited by the number of available qubits, researchers have not been able to simulate realistic large molecules with high precision. To overcome this barrier, researchers have proposed a wide range of distributed strategies [1-3]. In this tutorial, we take the distributed VQE based on Schmidt decomposition, proposed in [4], as an example to demonstrate how to implement distributed quantum algorithms using Paddle Quantum."
]
},
{
"cell_type": "markdown",
"id": "illegal-zealand",
"metadata": {},
"source": [
"## Schmidt Decomposition\n",
"We start with the following trivial decomposition for any pure state $|\\psi\\rangle$ of a composite system $AB$:\n",
"\n",
"$$\n",
"|\\psi\\rangle=\\sum_{ij}a_{ij}|i\\rangle\\otimes|j\\rangle,\n",
"\\tag{1}\n",
"$$\n",
"\n",
"where $|i\\rangle$ and $|j\\rangle$ are computational bases of subsystems $A$ and $B$ respectively, and $a_{ij}$ are elements of some complex matrix $a$. Then, we apply [singular value decomposition (SVD)](https://en.wikipedia.org/wiki/Singular_value_decomposition)\n",
"on $a$, i.e., $a = udv$ with $u,v$ being unitary and $d$ diagonal. Hence, $a_{ij}=\\sum_ku_{ik}d_{kk}v_{kj}$. \n",
"\n",
"By defining\n",
"\n",
"$$\n",
"\\begin{aligned}\n",
"|k_A\\rangle\\equiv & \\sum_iu_{ik}|i\\rangle=u|k\\rangle,\\\\\n",
"|k_B\\rangle\\equiv & \\sum_jv_{kj}|j\\rangle=v^T|k\\rangle,\\\\\n",
"\\lambda_k\\equiv & d_{kk},\n",
"\\end{aligned}\n",
"\\tag{2}\n",
"$$\n",
"\n",
"we may rewrite Eq. (1) as\n",
"\n",
"$$\n",
"\\begin{aligned}\n",
" |\\psi\\rangle &= \\sum_{ijk}u_{ik}d_{kk}v_{kj}|i\\rangle\\otimes|j\\rangle \\\\\n",
" &= \\sum_{k}\\lambda_{k}\\Big(\\sum_iu_{ik}|i\\rangle\\Big)\\otimes\\Big(\\sum_jv_{kj}|j\\rangle\\Big) \\\\\n",
" &=\\sum_{k}\\lambda_k(u|k\\rangle\\otimes v^T|k\\rangle)\\\\\n",
" &=\\sum_{k}\\lambda_k|k_A\\rangle\\otimes|k_B\\rangle.\n",
"\\end{aligned}\n",
"\\tag{3}\n",
"$$\n",
"\n",
"The decomposition of $|\\psi\\rangle$ into the form of $\\sum_k\\lambda_k|k_A\\rangle\\otimes|k_B\\rangle$ is known as its ***Schmidt decomposition*** [5], with $\\{\\lambda_k\\}_k$ called the *Schmidt coefficients* and the number of non-zero $\\lambda_k$'s its *Schmidt rank*. In fact, the property of SVD also guarantees that $\\lambda_k\\in\\mathbb{R}^+$ and $\\sum_k\\lambda_k^2=1$. "
]
},
{
"cell_type": "markdown",
"id": "looking-detail",
"metadata": {
"tags": []
},
"source": [
"## Distributed VQE Based on Schmidt Decomposition\n",
"\n",
"As a variation of the standard VQE [6], the distributed VQE also seeks to solve the ground state and its energy of an $N$-qubit Hamiltonian $\\hat{H}=\\sum_tc_t\\hat{H}_t^{(A)}\\otimes\\hat{H}_t^{(B)}$, where $\\hat{H}_t^{(A)},\\hat{H}_t^{(B)}$ are Hamiltonian terms on subsystems $A,B$ respectively (we have assumed that $A$, $B$ both have $N/2$ qubits).\n",
"\n",
"To start with, we write the trial wave function as\n",
"\n",
"$$\n",
"|\\psi\\rangle\\equiv\\sum_{k=1}^S\\lambda_k\\Big(U(\\boldsymbol{\\theta})|k\\rangle\\Big)\\otimes\\Big(V(\\boldsymbol{\\phi})|k\\rangle\\Big),\n",
"\\tag{4}\n",
"$$\n",
"\n",
"for some $\\boldsymbol{\\lambda}\\equiv(\\lambda_1, \\lambda_2,...,\\lambda_S)^T$ and $1\\leq S\\leq 2^{N/2}$ a user-defined constant. According to Schmidt decomposition, the target ground state also has the form of Eq. (4) and hence can be approximated with high precision by choosing appropriate parameters $\\boldsymbol{\\lambda}, \\boldsymbol{\\theta}$ and $\\boldsymbol{\\phi}$.\n",
"\n",
"Now, for all $i,j=1,...,S$, we evaluate the following terms on an $N/2$-qubit quantum computer:\n",
"\n",
"$$\n",
"\\begin{aligned}\n",
"E_{ijt}^A(\\boldsymbol{\\theta}) &\\equiv \\langle i|U^\\dagger(\\boldsymbol{\\theta}) \\hat{H}_t^{(A)} U(\\boldsymbol{\\theta})|j\\rangle,\\\\\n",
"E_{ijt}^B(\\boldsymbol{\\phi}) &\\equiv \\langle i|V^\\dagger(\\boldsymbol{\\phi}) \\hat{H}_t^{(B)} V(\\boldsymbol{\\phi}))|j\\rangle.\n",
"\\end{aligned}\n",
"\\tag{5}\n",
"$$\n",
"\n",
"Then, on a classical computer, we construct an $S\\times S$ dimensional matrix $M(\\boldsymbol{\\theta},\\boldsymbol{\\phi})$ according to\n",
"\n",
"$$\n",
"[M(\\boldsymbol{\\theta},\\boldsymbol{\\phi})]_{ij}\\equiv\\sum_tc_tE_{ijt}^A(\\boldsymbol{\\theta})E_{ijt}^B(\\boldsymbol{\\phi}).\n",
"\\tag{6}\n",
"$$\n",
"\n",
"In this way, the target ground state energy can be written as \n",
"$$\n",
"\\begin{aligned}\n",
"E_{tar} &= \\min_{\\boldsymbol{\\lambda}, \\boldsymbol{\\theta}, \\boldsymbol{\\phi}} \\langle{\\psi}|\\hat{H}|\\psi\\rangle \\\\\n",
" &= \\min_{\\boldsymbol{\\lambda}, \\boldsymbol{\\theta}, \\boldsymbol{\\phi}}\\Big(\\sum_{i,j=1}^S\\lambda_i\\lambda_j[M(\\boldsymbol{\\theta},\\boldsymbol{\\phi})]_{ij}\\Big)\\\\\n",
" &= \\min_{\\boldsymbol{\\theta}, \\boldsymbol{\\phi}} E(\\boldsymbol{\\theta},\\boldsymbol{\\phi}),\n",
"\\end{aligned}\n",
"\\tag{7}\n",
"$$\n",
"\n",
"where $E(\\boldsymbol{\\theta},\\boldsymbol{\\phi})\\equiv\\min_{\\boldsymbol{\\lambda}} \\boldsymbol{\\lambda}^T M(\\boldsymbol{\\theta},\\boldsymbol{\\phi})\\boldsymbol{\\lambda}$. By linear algebra, we see that $E(\\boldsymbol{\\theta},\\boldsymbol{\\phi})$ is exactly the minimal eigenvalue of $M(\\boldsymbol{\\theta},\\boldsymbol{\\phi})$, which can be solved using classical algorithms.\n",
"\n",
"Finally, we repeat the whole process and minimize $E(\\boldsymbol{\\theta},\\boldsymbol{\\phi})$ to approximate $E_{tar}$ using gradient-based optimization methods."
]
},
{
"cell_type": "markdown",
"id": "enabling-bulletin",
"metadata": {
"tags": []
},
"source": [
"## Paddle Quantum implementation\n",
"\n",
"First of all, we import necessary packages. Please make sure that you have *PaddlePaddle* >= 2.2.0 and *Paddle Quantum* >= 2.1.3, as we will use some of their latest features."
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "sized-girlfriend",
"metadata": {},
"outputs": [],
"source": [
"import time\n",
"import numpy as np\n",
"from matplotlib import pyplot as plt\n",
"\n",
"import paddle\n",
"from paddle_quantum.circuit import UAnsatz\n",
"from paddle_quantum.utils import pauli_str_to_matrix, schmidt_decompose"
]
},
{
"cell_type": "markdown",
"id": "central-internet",
"metadata": {},
"source": [
"Define some global constants:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "diverse-village",
"metadata": {},
"outputs": [],
"source": [
"N = 10 # Number of qubits\n",
"SEED = 16 # Fix a random seed\n",
"ITR = 100 # Set the number of learning iterations\n",
"LR = 0.1 # Set the learning rate\n",
"D = 3 # Set the depth for QNN"
]
},
{
"cell_type": "markdown",
"id": "strange-challenge",
"metadata": {},
"source": [
"The following function classically calculates the ground state information (the energy and the Schmidt rank of the ground state) of a Hamiltonian $H$, which we will use as the ground truth to benchmark our quantum models."
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "musical-ultimate",
"metadata": {},
"outputs": [],
"source": [
"def get_ground_state_info(H):\n",
"\n",
" # Calculate the eigenvalues and eigenvectors of H\n",
" vals, vecs = paddle.linalg.eigh(H)\n",
" # Retrieve the ground state\n",
" ground_state = vecs[:, 0].numpy()\n",
" # Retrieve the ground state energy\n",
" ground_state_energy = vals.tolist()[0]\n",
" print(f'The ground state energy is {ground_state_energy:.5f} Ha.')\n",
" # Run Schmidt decomposition on the ground state.\n",
" l, _, _ = schmidt_decompose(ground_state)\n",
" print(f'Schmidt rank of the ground state is {l.size}.')\n",
"\n",
" return ground_state_energy"
]
},
{
"cell_type": "markdown",
"id": "lesbian-employment",
"metadata": {},
"source": [
"Now, we generate a Hamiltonian and calculate its ground state information."
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "indie-detroit",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The ground state energy is -0.99783 Ha.\n",
"Schmidt rank of the ground state is 3.\n"
]
}
],
"source": [
"# Fix a random seed\n",
"np.random.seed(SEED)\n",
"\n",
"# Hard code a random a Hamiltonian\n",
"coefs = [-0.8886258, 0.453882]\n",
"pauli_str = ['x0,z1,z2,z4,x5,y6,y7,x8,x9', 'y0,x1,x2,x3,y4,x5,z6,z7,y8,x9']\n",
"pauli_str_A = ['x0,z1,z2,z4', 'y0,x1,x2,x3,y4'] # pauli substring for system A\n",
"pauli_str_B = ['x0,y1,y2,x3,x4', 'x0,z1,z2,y3,x4'] # pauli substring for system B\n",
"\n",
"# Convert relavent object into Tensor form\n",
"H_mtr = paddle.to_tensor(pauli_str_to_matrix(zip(coefs, pauli_str), n=N))\n",
"coefs = paddle.to_tensor(coefs)\n",
"H_A = [pauli_str_to_matrix([[1., pstr]], n=N//2) for pstr in pauli_str_A]\n",
"H_A = paddle.to_tensor(np.stack(H_A))\n",
"H_B = [pauli_str_to_matrix([[1., pstr]], n=N-N//2) for pstr in pauli_str_B]\n",
"H_B = paddle.to_tensor(np.stack(H_B))\n",
"\n",
"# calculate the ground state information\n",
"ground_state_energy = get_ground_state_info(H_mtr)"
]
},
{
"cell_type": "markdown",
"id": "dietary-hotel",
"metadata": {},
"source": [
"Now that we have prepared a Hamiltonian, we may build a distributed VQE to solve it."
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "international-wesley",
"metadata": {},
"outputs": [],
"source": [
"# Construct parameterized circuit\n",
"def U_theta(param, N, D):\n",
" \n",
" cir = UAnsatz(N) # Initialize an N-qubit-width circuit\n",
" cir.complex_entangled_layer(param, D) # Add quantum gates\n",
" return cir.U # Retrieve the unitary matrix for the parameterized circuit\n",
"\n",
"# Apply a parameterized circuit on the conputational bases\n",
"# and return a tensor of shape [2**N, num_states]\n",
"def output_states(theta, num_states, N, D):\n",
" # Create num_states-many computational bases\n",
" basis = paddle.eye(2**N, num_states)\n",
" \n",
" # Acquire a parameterized circuit\n",
" U = U_theta(theta, N, D)\n",
" \n",
" # Apply the parameterized circuit on these bases\n",
" vec = U @ basis \n",
" \n",
" return vec"
]
},
{
"cell_type": "markdown",
"id": "disturbed-strap",
"metadata": {},
"source": [
"The code below is core to this tutorial. Please compare them with the formulae given in the beginning section and make sure that they are well understood."
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "normal-leader",
"metadata": {},
"outputs": [],
"source": [
"# Construct the distributed model\n",
"class DistributedVQE(paddle.nn.Layer):\n",
" def __init__(self, N, D, S):\n",
" super().__init__()\n",
" paddle.seed(SEED)\n",
"\n",
" # Define constant S\n",
" self.S = S\n",
" self.N, self.D = N, D\n",
" # Initialize the parameter lists theta, phi, filled by a uniform distribution in [0, 2*pi]\n",
" self.theta = self.create_parameter(shape=[D, N//2, 3], dtype=\"float64\",\n",
" default_initializer=paddle.nn.initializer.Uniform(low=0.0, high=2*np.pi))\n",
" self.phi = self.create_parameter(shape=[D, N - N//2, 3], dtype=\"float64\",\n",
" default_initializer=paddle.nn.initializer.Uniform(low=0.0, high=2*np.pi))\n",
" \n",
" # The core logic of distributed VQE\n",
" def forward(self):\n",
" # Obtain U|k> and V|k> for subsystems A and B respectively \n",
" vec_A = output_states(self.theta, self.S, self.N//2, self.D)\n",
" vec_B = output_states(self.phi, self.S, self.N - self.N//2, self.D)\n",
" \n",
" # Calculate tensor E_A, E_B, which have elements E_{ijt}^A and E_{ijt}^B, as per defined in above\n",
" E_A = vec_A.conj().t() @ H_A @ vec_A\n",
" E_B = vec_B.conj().t() @ H_B @ vec_B\n",
" M = (coefs.reshape([-1, 1, 1]) * E_A * E_B).sum(0)\n",
"\n",
" # Find the minimal eigenvalue of M\n",
" eigval = paddle.linalg.eigvalsh(M)\n",
" loss = eigval[0]\n",
" \n",
" return loss"
]
},
{
"cell_type": "markdown",
"id": "independent-undergraduate",
"metadata": {},
"source": [
"Define training function."
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "liberal-mountain",
"metadata": {},
"outputs": [],
"source": [
"def train(model):\n",
" start_time = time.time() # To calculate the running time of this function\n",
" \n",
" # We will use Adam, a gradient-based optimizer to optimize theta and phi\n",
" opt = paddle.optimizer.Adam(learning_rate=LR, parameters=model.parameters())\n",
" summary_loss = [] # Save loss history\n",
"\n",
" # Optimization iteration\n",
" for itr in range(ITR):\n",
"\n",
" # Forward propagation to calculates the loss function\n",
" loss = model()\n",
"\n",
" # Backward propagation to optimize the loss function\n",
" loss.backward()\n",
" opt.minimize(loss)\n",
" opt.clear_grad()\n",
"\n",
" # Update optimization result\n",
" summary_loss.append(loss.numpy())\n",
"\n",
" # Print itermediary result\n",
" if (itr+1) % 20 == 0:\n",
" print(f\"iter: {itr+1}, loss: {loss.tolist()[0]: .4f} Ha\")\n",
"\n",
" print(f'Ground truth is {ground_state_energy:.4f} Ha')\n",
" print(f'Training took {time.time() - start_time:.2f}s')\n",
" \n",
" plt.plot(list(range(ITR)), summary_loss, color='r', label='loss')\n",
" plt.hlines(y=ground_state_energy, xmin=0, xmax=ITR, linestyle=':', label='ground truth')\n",
" plt.legend()\n",
" plt.title(f'Loss for {type(model).__name__} on a {N}-qubit Hamiltonian')\n",
" plt.show()"
]
},
{
"cell_type": "markdown",
"id": "civic-distance",
"metadata": {},
"source": [
"Now, we are ready to instantiate the model and train it!"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "compressed-reviewer",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"iter: 20, loss: -0.9244 Ha\n",
"iter: 40, loss: -0.9906 Ha\n",
"iter: 60, loss: -0.9968 Ha\n",
"iter: 80, loss: -0.9977 Ha\n",
"iter: 100, loss: -0.9978 Ha\n",
"Ground truth is -0.9978 Ha\n",
"Training took 13.01s\n"
]
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# Note that we manually set S = 4 as the Hamiltonian we just created interacts weakly across the subsystems.\n",
"# (See the Conclusion section for further description)\n",
"vqe = DistributedVQE(N, D, S=4)\n",
"train(vqe)"
]
},
{
"cell_type": "markdown",
"id": "convenient-receiver",
"metadata": {},
"source": [
"We have plotted the actual ground state energy as a dotted line in the figure above. We see that the loss curve converges to the dotted line, meaning that our distributed VQE successfully found the ground state energy of the Hamiltonian. However, to properly evaluate our model, we need to compare it with the standard VQE, which we build below:"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "intensive-pickup",
"metadata": {},
"outputs": [],
"source": [
"class StandardVQE(paddle.nn.Layer):\n",
" def __init__(self, N, D):\n",
" super().__init__()\n",
" paddle.seed(SEED)\n",
" self.N, self.D = N, D\n",
" self.theta = self.create_parameter(shape=[D, N, 3], dtype=\"float64\",\n",
" default_initializer=paddle.nn.initializer.Uniform(low=0.0, high=2*np.pi))\n",
" \n",
" def forward(self):\n",
" vec = output_states(self.theta, 1, self.N, self.D)\n",
" loss = vec.conj().t() @ H_mtr @ vec\n",
" return loss.cast('float64').flatten()"
]
},
{
"cell_type": "markdown",
"id": "dress-vulnerability",
"metadata": {},
"source": [
"Instantiate and train the StandardVQE."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a35f3eb4",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"iter: 20, loss: -0.8365 Ha\n",
"iter: 40, loss: -0.9852 Ha\n",
"iter: 60, loss: -0.9958 Ha\n",
"iter: 80, loss: -0.9975 Ha\n",
"iter: 100, loss: -0.9978 Ha\n",
"Ground truth is -0.9978 Ha\n",
"Training took 721.76s\n"
]
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"svqe = StandardVQE(N, D)\n",
"train(svqe) # Train the standard VQE "
]
},
{
"cell_type": "markdown",
"id": "centered-sheffield",
"metadata": {},
"source": [
"Interestingly, by comparing the running time of the two models, we find that the distributed model runs 50 times faster than the standard VQE! In fact, this is easy to understand: in a distributed model, we only need to simulate two $N/2$-qubit unitary transformations, which is, of course, much more time- and space-efficient than simulating an $N$-qubit unitary transformation in the standard VQE."
]
},
{
"cell_type": "markdown",
"id": "blocked-determination",
"metadata": {
"tags": []
},
"source": [
"## Conclusion\n",
"\n",
"In this tutorial, we built a distributed VQE and demonstrated some of its advantages:\n",
"- The capability of NISQ devices is expanded. Distributed strategies enable the deployment of quantum algorithms which require qubits that exceed the capability of current hardware.\n",
"- The computation efficiency is improved. For classical simulation of quantum processes, distributed algorithms reduce the dimension of unitary matrices, hence reducing the space and time cost for simulating them.\n",
"\n",
"In the meantime, one must note that $S$, as a user-defined constant, plays a key role in the training accuracy and efficiency:\n",
"- For Hamiltonians which encode weak inter-subsystem interactions, their ground states are weakly entangled across the subsystems [7]. Hence, the Schmidt ranks are small and can be accurately and efficiently simulated by a small $S$. In fact, our example and most physically and chemically interesting Hamiltonians fall into this category.\n",
"- In contrast, for Hamiltonians which encode strong inter-subsystem interactions, their ground states are strongly entangled. Hence, a large $S$ may be required. But anyway, $S$ is upper-bounded by $2^{N/2}$ and thus the dimension of $M$ is upper-bounded by $2^{N/2}\\times2^{N/2}$, which is still much smaller than the dimension of the initial Hamiltonian ($2^{N}\\times 2^{N}$). Consequently, the efficiency of this algorithm is always better than the purely classical simulation."
]
},
{
"cell_type": "markdown",
"id": "suspended-monroe",
"metadata": {
"jp-MarkdownHeadingCollapsed": true,
"tags": []
},
"source": [
"_______\n",
"\n",
"# References\n",
"\n",
"[1] Fujii, Keisuke, et al. \"Deep Variational Quantum Eigensolver: a divide-and-conquer method for solving a larger problem with smaller size quantum computers.\" [arXiv preprint arXiv:2007.10917 (2020)](https://arxiv.org/abs/2007.10917).\n",
"\n",
"[2] Zhang, Yu, et al. \"Variational Quantum Eigensolver with Reduced Circuit Complexity.\" [arXiv preprint arXiv:2106.07619(2021)](https://arxiv.org/abs/2106.07619).\n",
"\n",
"[3] Peng, Tianyi et al. \"Simulating Large Quantum Circuits On A Small Quantum Computer\". [Physical Review Letters 125.15, (2020): 150504](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.125.150504).\n",
"\n",
"[4] Eddins, Andrew, et al. \"Doubling the size of quantum simulators by entanglement forging.\" [arXiv preprint arXiv:2104.10220 (2021)](https://arxiv.org/abs/2104.10220).\n",
"\n",
"[5] Nielsen, Michael A., and Isaac L. Chuang. Quantum Computation and Quantum Information. Cambridge University Press, 2010.\n",
"\n",
"[6] Moll, Nikolaj, et al. \"Quantum optimization using variational algorithms on near-term quantum devices.\" [Quantum Science and Technology 3.3 (2018): 030503](https://iopscience.iop.org/article/10.1088/2058-9565/aab822).\n",
"\n",
"[7] Khatri, Sumeet, and Mark M. Wilde. \"Principles of quantum communication theory: A modern approach.\" [arXiv preprint arXiv:2011.04672 (2020)](https://arxiv.org/abs/2011.04672)."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
...@@ -430,7 +430,7 @@ ...@@ -430,7 +430,7 @@
"\n", "\n",
"[3] Somma, R. D., Boixo, S., Barnum, H. & Knill, E. Quantum Simulations of Classical Annealing Processes. [Phys. Rev. Lett. 101, 130504 (2008).](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.101.130504)\n", "[3] Somma, R. D., Boixo, S., Barnum, H. & Knill, E. Quantum Simulations of Classical Annealing Processes. [Phys. Rev. Lett. 101, 130504 (2008).](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.101.130504)\n",
"\n", "\n",
"[4] Wang, Y., Li, G. & Wang, X. Variational quantum Gibbs state preparation with a truncated Taylor series. [arXiv:2005.08797 (2020).](https://arxiv.org/pdf/2005.08797.pdf)" "[4] Wang, Y., Li, G. & Wang, X. Variational quantum Gibbs state preparation with a truncated Taylor series. [Phys. Rev. A 16, 054035 (2021).](https://journals.aps.org/prapplied/abstract/10.1103/PhysRevApplied.16.054035)"
] ]
} }
], ],
...@@ -450,7 +450,7 @@ ...@@ -450,7 +450,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.8.3" "version": "3.7.10"
}, },
"toc": { "toc": {
"base_numbering": 1, "base_numbering": 1,
......
...@@ -411,7 +411,7 @@ ...@@ -411,7 +411,7 @@
"\n", "\n",
"[3] Somma, R. D., Boixo, S., Barnum, H. & Knill, E. Quantum Simulations of Classical Annealing Processes. [Phys. Rev. Lett. 101, 130504 (2008).](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.101.130504)\n", "[3] Somma, R. D., Boixo, S., Barnum, H. & Knill, E. Quantum Simulations of Classical Annealing Processes. [Phys. Rev. Lett. 101, 130504 (2008).](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.101.130504)\n",
"\n", "\n",
"[4] Wang, Y., Li, G. & Wang, X. Variational quantum Gibbs state preparation with a truncated Taylor series. [arXiv:2005.08797 (2020).](https://arxiv.org/pdf/2005.08797.pdf)" "[4] Wang, Y., Li, G. & Wang, X. Variational quantum Gibbs state preparation with a truncated Taylor series. [Phys. Rev. A 16, 054035 (2021).](https://journals.aps.org/prapplied/abstract/10.1103/PhysRevApplied.16.054035)"
] ]
} }
], ],
...@@ -431,7 +431,7 @@ ...@@ -431,7 +431,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.8.3" "version": "3.7.10"
}, },
"toc": { "toc": {
"base_numbering": 1, "base_numbering": 1,
......
...@@ -2,8 +2,9 @@ ...@@ -2,8 +2,9 @@
"cells": [ "cells": [
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"# 子空间搜索-量子变分本征求解器\n", "# 子空间搜索-变分量子本征求解器\n",
"\n", "\n",
"<em> Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved. </em>\n", "<em> Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved. </em>\n",
"\n", "\n",
...@@ -12,12 +13,18 @@ ...@@ -12,12 +13,18 @@
"- 在本案例中,我们将展示如何通过 Paddle Quantum 训练量子神经网络来求解量子系统的整个能量谱。\n", "- 在本案例中,我们将展示如何通过 Paddle Quantum 训练量子神经网络来求解量子系统的整个能量谱。\n",
"\n", "\n",
"- 首先,让我们通过下面几行代码引入必要的 library 和 package。" "- 首先,让我们通过下面几行代码引入必要的 library 和 package。"
], ]
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 1, "execution_count": 1,
"metadata": {
"ExecuteTime": {
"end_time": "2021-04-30T09:12:57.571029Z",
"start_time": "2021-04-30T09:12:54.960356Z"
}
},
"outputs": [],
"source": [ "source": [
"import numpy\n", "import numpy\n",
"from numpy import pi as PI\n", "from numpy import pi as PI\n",
...@@ -25,17 +32,11 @@ ...@@ -25,17 +32,11 @@
"from paddle import matmul\n", "from paddle import matmul\n",
"from paddle_quantum.circuit import UAnsatz\n", "from paddle_quantum.circuit import UAnsatz\n",
"from paddle_quantum.utils import random_pauli_str_generator, pauli_str_to_matrix, dagger" "from paddle_quantum.utils import random_pauli_str_generator, pauli_str_to_matrix, dagger"
], ]
"outputs": [],
"metadata": {
"ExecuteTime": {
"end_time": "2021-04-30T09:12:57.571029Z",
"start_time": "2021-04-30T09:12:54.960356Z"
}
}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"## 背景\n", "## 背景\n",
"\n", "\n",
...@@ -47,67 +48,73 @@ ...@@ -47,67 +48,73 @@
"\n", "\n",
"- 对于具体需要分析的分子,我们需要其几何构型(geometry)、电荷(charge)以及自旋多重度(spin multiplicity)等多项信息来建模获取描述系统的 Hamilton 量。具体的,通过我们内置的量子化学工具包可以利用 fermionic-to-qubit 映射的技术来输出目标分子的量子比特 Hamilton 量表示。\n", "- 对于具体需要分析的分子,我们需要其几何构型(geometry)、电荷(charge)以及自旋多重度(spin multiplicity)等多项信息来建模获取描述系统的 Hamilton 量。具体的,通过我们内置的量子化学工具包可以利用 fermionic-to-qubit 映射的技术来输出目标分子的量子比特 Hamilton 量表示。\n",
"- 作为简单的入门案例,我们在这里提供一个简单的随机双量子比特 Hamilton 量作为例子。" "- 作为简单的入门案例,我们在这里提供一个简单的随机双量子比特 Hamilton 量作为例子。"
], ]
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 3, "execution_count": 3,
"source": [
"N = 2 # 量子比特数/量子神经网络的宽度\n",
"SEED = 14 # 固定随机种子"
],
"outputs": [],
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:12:57.580461Z", "end_time": "2021-04-30T09:12:57.580461Z",
"start_time": "2021-04-30T09:12:57.574080Z" "start_time": "2021-04-30T09:12:57.574080Z"
} }
} },
"outputs": [],
"source": [
"N = 2 # 量子比特数/量子神经网络的宽度\n",
"SEED = 14 # 固定随机种子"
]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 8, "execution_count": 8,
"source": [ "metadata": {
"# 生成用泡利字符串表示的随机哈密顿量\n", "ExecuteTime": {
"numpy.random.seed(SEED)\n", "end_time": "2021-04-30T09:12:57.604652Z",
"hamiltonian = random_pauli_str_generator(N, terms=10)\n", "start_time": "2021-04-30T09:12:57.592553Z"
"print(\"Random Hamiltonian in Pauli string format = \\n\", hamiltonian)\n", }
"\n", },
"# 生成 Hamilton 量的矩阵信息\n",
"H = pauli_str_to_matrix(hamiltonian, N)"
],
"outputs": [ "outputs": [
{ {
"output_type": "stream",
"name": "stdout", "name": "stdout",
"output_type": "stream",
"text": [ "text": [
"Random Hamiltonian in Pauli string format = \n", "Random Hamiltonian in Pauli string format = \n",
" [[0.9152074787317819, 'x1,y0'], [-0.2717604556798945, 'z0'], [0.3628495008719168, 'x0'], [-0.5050129214094752, 'x1'], [-0.6971554357833791, 'y0,x1'], [0.8651151857574237, 'x0,y1'], [0.7409989105435002, 'y0'], [-0.39981603921243236, 'y0'], [0.06862640764702, 'z0'], [-0.7647553733438246, 'y1']]\n" " [[0.9152074787317819, 'x1,y0'], [-0.2717604556798945, 'z0'], [0.3628495008719168, 'x0'], [-0.5050129214094752, 'x1'], [-0.6971554357833791, 'y0,x1'], [0.8651151857574237, 'x0,y1'], [0.7409989105435002, 'y0'], [-0.39981603921243236, 'y0'], [0.06862640764702, 'z0'], [-0.7647553733438246, 'y1']]\n"
] ]
} }
], ],
"metadata": { "source": [
"ExecuteTime": { "# 生成用泡利字符串表示的随机哈密顿量\n",
"end_time": "2021-04-30T09:12:57.604652Z", "numpy.random.seed(SEED)\n",
"start_time": "2021-04-30T09:12:57.592553Z" "hamiltonian = random_pauli_str_generator(N, terms=10)\n",
} "print(\"Random Hamiltonian in Pauli string format = \\n\", hamiltonian)\n",
} "\n",
"# 生成 Hamilton 量的矩阵信息\n",
"H = pauli_str_to_matrix(hamiltonian, N)"
]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"## 搭建量子神经网络\n", "## 搭建量子神经网络\n",
"\n", "\n",
"- 在实现 SSVQE 的过程中,我们首先需要设计量子神经网络(quantum neural network, QNN),也即参数化量子电路。在本教程中,我们提供一个预设的适用于双量子比特的通用量子电路模板。理论上,该模板具有足够强大的表达能力可以表示任意的双量子比特逻辑运算 [5]。具体的实现方式是需要 3 个 $CNOT$ 门加上任意 15 个单比特旋转门 $\\in \\{R_y, R_z\\}$。\n", "- 在实现 SSVQE 的过程中,我们首先需要设计量子神经网络(quantum neural network, QNN),也即参数化量子电路。在本教程中,我们提供一个预设的适用于双量子比特的通用量子电路模板。理论上,该模板具有足够强大的表达能力可以表示任意的双量子比特逻辑运算 [5]。具体的实现方式是需要 3 个 $CNOT$ 门加上任意 15 个单比特旋转门 $\\in \\{R_y, R_z\\}$。\n",
"\n", "\n",
"- 初始化其中的变量参数,${\\bf{\\theta}}$ 代表我们量子神经网络中的参数组成的向量,一共有 15 个参数。" "- 初始化其中的变量参数,${\\bf{\\theta}}$ 代表我们量子神经网络中的参数组成的向量,一共有 15 个参数。"
], ]
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 9, "execution_count": 9,
"metadata": {
"ExecuteTime": {
"end_time": "2021-04-30T09:12:57.673600Z",
"start_time": "2021-04-30T09:12:57.664882Z"
}
},
"outputs": [],
"source": [ "source": [
"THETA_SIZE = 15 # 量子神经网络中参数的数量\n", "THETA_SIZE = 15 # 量子神经网络中参数的数量\n",
"\n", "\n",
...@@ -123,17 +130,11 @@ ...@@ -123,17 +130,11 @@
"\n", "\n",
" # 返回量子神经网络的电路\n", " # 返回量子神经网络的电路\n",
" return cir" " return cir"
], ]
"outputs": [],
"metadata": {
"ExecuteTime": {
"end_time": "2021-04-30T09:12:57.673600Z",
"start_time": "2021-04-30T09:12:57.664882Z"
}
}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"## 配置训练模型——损失函数\n", "## 配置训练模型——损失函数\n",
"\n", "\n",
...@@ -148,12 +149,18 @@ ...@@ -148,12 +149,18 @@
"$$\n", "$$\n",
"\\mathcal{L}(\\boldsymbol{\\theta}) = \\sum_{k=1}^{2^n}w_k*\\left\\langle {\\psi_k \\left( {\\bf{\\theta }} \\right)} \\right|H\\left| {\\psi_k \\left( {\\bf{\\theta }} \\right)} \\right\\rangle. \\tag{1}\n", "\\mathcal{L}(\\boldsymbol{\\theta}) = \\sum_{k=1}^{2^n}w_k*\\left\\langle {\\psi_k \\left( {\\bf{\\theta }} \\right)} \\right|H\\left| {\\psi_k \\left( {\\bf{\\theta }} \\right)} \\right\\rangle. \\tag{1}\n",
"$$" "$$"
], ]
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 10, "execution_count": 10,
"metadata": {
"ExecuteTime": {
"end_time": "2021-04-30T09:12:58.591349Z",
"start_time": "2021-04-30T09:12:58.577120Z"
}
},
"outputs": [],
"source": [ "source": [
"class Net(paddle.nn.Layer):\n", "class Net(paddle.nn.Layer):\n",
" def __init__(self, shape, dtype='float64'):\n", " def __init__(self, shape, dtype='float64'):\n",
...@@ -186,51 +193,74 @@ ...@@ -186,51 +193,74 @@
" loss += weight * loss_components[i]\n", " loss += weight * loss_components[i]\n",
" \n", " \n",
" return loss, loss_components, cir" " return loss, loss_components, cir"
], ]
"outputs": [],
"metadata": {
"ExecuteTime": {
"end_time": "2021-04-30T09:12:58.591349Z",
"start_time": "2021-04-30T09:12:58.577120Z"
}
}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"## 配置训练模型——模型参数\n", "## 配置训练模型——模型参数\n",
"在进行量子神经网络的训练之前,我们还需要进行一些训练的超参数设置,主要是学习速率(learning rate, LR)、迭代次数(iteration, ITR。这里我们设定学习速率为 0.3,迭代次数为 50 次。读者不妨自行调整来直观感受下超参数调整对训练效果的影响。" "在进行量子神经网络的训练之前,我们还需要进行一些训练的超参数设置,主要是学习速率(learning rate, LR)、迭代次数(iteration, ITR。这里我们设定学习速率为 0.3,迭代次数为 50 次。读者不妨自行调整来直观感受下超参数调整对训练效果的影响。"
], ]
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 11, "execution_count": 11,
"source": [
"ITR = 100 # 设置训练的总迭代次数\n",
"LR = 0.3 # 设置学习速率"
],
"outputs": [],
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:12:59.351881Z", "end_time": "2021-04-30T09:12:59.351881Z",
"start_time": "2021-04-30T09:12:59.343240Z" "start_time": "2021-04-30T09:12:59.343240Z"
} }
} },
"outputs": [],
"source": [
"ITR = 100 # 设置训练的总迭代次数\n",
"LR = 0.3 # 设置学习速率"
]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"## 进行训练\n", "## 进行训练\n",
"- 当训练模型的各项参数都设置完成后,我们将数据转化为 PaddlePaddle 动态图中的张量,进而进行量子神经网络的训练。\n", "- 当训练模型的各项参数都设置完成后,我们将数据转化为 PaddlePaddle 动态图中的张量,进而进行量子神经网络的训练。\n",
"- 过程中我们用的是 Adam Optimizer,也可以调用 PaddlePaddle 中提供的其他优化器。\n", "- 过程中我们用的是 Adam Optimizer,也可以调用 PaddlePaddle 中提供的其他优化器。\n",
"- 我们可以将训练过程中的每一轮 loss 打印出来。" "- 我们可以将训练过程中的每一轮 loss 打印出来。"
], ]
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 13, "execution_count": 13,
"metadata": {
"ExecuteTime": {
"end_time": "2021-04-30T09:13:07.503094Z",
"start_time": "2021-04-30T09:13:04.968574Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"iter: 10 loss: -4.5668\n",
"iter: 20 loss: -5.3998\n",
"iter: 30 loss: -5.6210\n",
"iter: 40 loss: -5.8872\n",
"iter: 50 loss: -5.9246\n",
"iter: 60 loss: -5.9471\n",
"iter: 70 loss: -5.9739\n",
"iter: 80 loss: -5.9833\n",
"iter: 90 loss: -5.9846\n",
"iter: 100 loss: -5.9848\n",
"\n",
"训练后的电路:\n",
"--U----x----Rz(-1.18)----*-----------------x----U--\n",
" | | | \n",
"--U----*----Ry(-0.03)----x----Ry(2.362)----*----U--\n",
" \n"
]
}
],
"source": [ "source": [
"paddle.seed(SEED)\n", "paddle.seed(SEED)\n",
" \n", " \n",
...@@ -261,40 +291,11 @@ ...@@ -261,40 +291,11 @@
" if itr == ITR:\n", " if itr == ITR:\n",
" print(\"\\n训练后的电路:\")\n", " print(\"\\n训练后的电路:\")\n",
" print(cir)" " print(cir)"
], ]
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"iter: 10 loss: -4.5668\n",
"iter: 20 loss: -5.3998\n",
"iter: 30 loss: -5.6210\n",
"iter: 40 loss: -5.8872\n",
"iter: 50 loss: -5.9246\n",
"iter: 60 loss: -5.9471\n",
"iter: 70 loss: -5.9739\n",
"iter: 80 loss: -5.9833\n",
"iter: 90 loss: -5.9846\n",
"iter: 100 loss: -5.9848\n",
"\n",
"训练后的电路:\n",
"--U----x----Rz(-1.18)----*-----------------x----U--\n",
" | | | \n",
"--U----*----Ry(-0.03)----x----Ry(2.362)----*----U--\n",
" \n"
]
}
],
"metadata": {
"ExecuteTime": {
"end_time": "2021-04-30T09:13:07.503094Z",
"start_time": "2021-04-30T09:13:04.968574Z"
}
}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"## 测试效果\n", "## 测试效果\n",
"\n", "\n",
...@@ -302,12 +303,28 @@ ...@@ -302,12 +303,28 @@
"- 理论值由 NumPy 中的工具来求解哈密顿量的各个本征值;\n", "- 理论值由 NumPy 中的工具来求解哈密顿量的各个本征值;\n",
"- 我们将训练 QNN 得到的各个能级的能量和理想情况下的理论值进行比对。\n", "- 我们将训练 QNN 得到的各个能级的能量和理想情况下的理论值进行比对。\n",
"- 可以看到,SSVQE 训练输出的值与理想值高度接近。" "- 可以看到,SSVQE 训练输出的值与理想值高度接近。"
], ]
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 15, "execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The estimated ground state energy is: [-2.18762366]\n",
"The theoretical ground state energy is: -2.18790201165885\n",
"The estimated 1st excited state energy is: [-0.13721024]\n",
"The theoretical 1st excited state energy is: -0.13704127143749587\n",
"The estimated 2nd excited state energy is: [0.85251457]\n",
"The theoretical 2nd excited state energy is: 0.8523274042087416\n",
"The estimated 3rd excited state energy is: [1.47231932]\n",
"The theoretical 3rd excited state energy is: 1.4726158788876045\n"
]
}
],
"source": [ "source": [
"def output_ordinalvalue(num):\n", "def output_ordinalvalue(num):\n",
" r\"\"\"\n", " r\"\"\"\n",
...@@ -339,27 +356,11 @@ ...@@ -339,27 +356,11 @@
" print('The theoretical {} excited state energy is: {}'.format(\n", " print('The theoretical {} excited state energy is: {}'.format(\n",
" output_ordinalvalue(i), numpy.linalg.eigh(H)[0][i])\n", " output_ordinalvalue(i), numpy.linalg.eigh(H)[0][i])\n",
" )" " )"
], ]
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"The estimated ground state energy is: [-2.18762366]\n",
"The theoretical ground state energy is: -2.18790201165885\n",
"The estimated 1st excited state energy is: [-0.13721024]\n",
"The theoretical 1st excited state energy is: -0.13704127143749587\n",
"The estimated 2nd excited state energy is: [0.85251457]\n",
"The theoretical 2nd excited state energy is: 0.8523274042087416\n",
"The estimated 3rd excited state energy is: [1.47231932]\n",
"The theoretical 3rd excited state energy is: 1.4726158788876045\n"
]
}
],
"metadata": {}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"_______\n", "_______\n",
"\n", "\n",
...@@ -374,14 +375,17 @@ ...@@ -374,14 +375,17 @@
"[4] Nakanishi, K. M., Mitarai, K. & Fujii, K. Subspace-search variational quantum eigensolver for excited states. [Phys. Rev. Res. 1, 033062 (2019).](https://journals.aps.org/prresearch/pdf/10.1103/PhysRevResearch.1.033062)\n", "[4] Nakanishi, K. M., Mitarai, K. & Fujii, K. Subspace-search variational quantum eigensolver for excited states. [Phys. Rev. Res. 1, 033062 (2019).](https://journals.aps.org/prresearch/pdf/10.1103/PhysRevResearch.1.033062)\n",
"\n", "\n",
"[5] Vatan, F. & Williams, C. Optimal quantum circuits for general two-qubit gates. [Phys. Rev. A 69, 032315 (2004).](https://journals.aps.org/pra/abstract/10.1103/PhysRevA.69.032315)" "[5] Vatan, F. & Williams, C. Optimal quantum circuits for general two-qubit gates. [Phys. Rev. A 69, 032315 (2004).](https://journals.aps.org/pra/abstract/10.1103/PhysRevA.69.032315)"
], ]
"metadata": {}
} }
], ],
"metadata": { "metadata": {
"interpreter": {
"hash": "1ba3360425d54dc61cc146cb8ddc529b6d51be6719655a3ca16cefddffc9595a"
},
"kernelspec": { "kernelspec": {
"name": "python3", "display_name": "Python 3",
"display_name": "Python 3.8.10 64-bit ('paddle_quantum_test': conda)" "language": "python",
"name": "python3"
}, },
"language_info": { "language_info": {
"codemirror_mode": { "codemirror_mode": {
...@@ -393,7 +397,7 @@ ...@@ -393,7 +397,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.8.10" "version": "3.7.10"
}, },
"toc": { "toc": {
"base_numbering": 1, "base_numbering": 1,
...@@ -407,11 +411,8 @@ ...@@ -407,11 +411,8 @@
"toc_position": {}, "toc_position": {},
"toc_section_display": true, "toc_section_display": true,
"toc_window_display": false "toc_window_display": false
},
"interpreter": {
"hash": "1ba3360425d54dc61cc146cb8ddc529b6d51be6719655a3ca16cefddffc9595a"
} }
}, },
"nbformat": 4, "nbformat": 4,
"nbformat_minor": 4 "nbformat_minor": 4
} }
\ No newline at end of file
...@@ -117,7 +117,7 @@ ...@@ -117,7 +117,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 1, "execution_count": 2,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:13:45.528201Z", "end_time": "2021-04-30T09:13:45.528201Z",
...@@ -152,7 +152,7 @@ ...@@ -152,7 +152,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 2, "execution_count": 3,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:13:45.545018Z", "end_time": "2021-04-30T09:13:45.545018Z",
...@@ -164,24 +164,24 @@ ...@@ -164,24 +164,24 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"FCI energy for H2_sto-3g_singlet (2 electrons) is -1.137283834485513.\n", "FCI energy for H2_sto-3g_singlet (2 electrons) is -1.1372838344855134.\n",
"\n", "\n",
"The generated h2 Hamiltonian is \n", "The generated h2 Hamiltonian is \n",
" -0.09706626861762556 I\n", " -0.0970662686176252 I\n",
"-0.04530261550868938 X0, X1, Y2, Y3\n", "-0.04530261550868938 X0, X1, Y2, Y3\n",
"0.04530261550868938 X0, Y1, Y2, X3\n", "0.04530261550868938 X0, Y1, Y2, X3\n",
"0.04530261550868938 Y0, X1, X2, Y3\n", "0.04530261550868938 Y0, X1, X2, Y3\n",
"-0.04530261550868938 Y0, Y1, X2, X3\n", "-0.04530261550868938 Y0, Y1, X2, X3\n",
"0.1714128263940239 Z0\n", "0.1714128263940238 Z0\n",
"0.16868898168693286 Z0, Z1\n", "0.16868898168693292 Z0, Z1\n",
"0.12062523481381837 Z0, Z2\n", "0.12062523481381847 Z0, Z2\n",
"0.16592785032250773 Z0, Z3\n", "0.1659278503225078 Z0, Z3\n",
"0.17141282639402394 Z1\n", "0.17141282639402383 Z1\n",
"0.16592785032250773 Z1, Z2\n", "0.1659278503225078 Z1, Z2\n",
"0.12062523481381837 Z1, Z3\n", "0.12062523481381847 Z1, Z3\n",
"-0.2234315367466399 Z2\n", "-0.22343153674664024 Z2\n",
"0.17441287610651626 Z2, Z3\n", "0.17441287610651632 Z2, Z3\n",
"-0.2234315367466399 Z3\n" "-0.2234315367466403 Z3\n"
] ]
} }
], ],
...@@ -203,7 +203,7 @@ ...@@ -203,7 +203,7 @@
"molecular_hamiltonian = qchem.spin_hamiltonian(molecule=molecule,\n", "molecular_hamiltonian = qchem.spin_hamiltonian(molecule=molecule,\n",
" filename=None, \n", " filename=None, \n",
" multiplicity=1, \n", " multiplicity=1, \n",
" mapping_method = 'jordan_wigner',)\n", " mapping_method='jordan_wigner',)\n",
"# 打印结果\n", "# 打印结果\n",
"print(\"\\nThe generated h2 Hamiltonian is \\n\", molecular_hamiltonian)" "print(\"\\nThe generated h2 Hamiltonian is \\n\", molecular_hamiltonian)"
] ]
...@@ -236,7 +236,7 @@ ...@@ -236,7 +236,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 3, "execution_count": 4,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
...@@ -281,7 +281,7 @@ ...@@ -281,7 +281,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 4, "execution_count": 5,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
...@@ -318,7 +318,7 @@ ...@@ -318,7 +318,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 5, "execution_count": 6,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:14:03.744957Z", "end_time": "2021-04-30T09:14:03.744957Z",
...@@ -344,30 +344,30 @@ ...@@ -344,30 +344,30 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 6, "execution_count": 7,
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"iter: 20 loss: -1.0621\n", "iter: 20 loss: -1.0861\n",
"iter: 20 Ground state energy: -1.0621 Ha\n", "iter: 20 Ground state energy: -1.0861 Ha\n",
"iter: 40 loss: -1.1305\n", "iter: 40 loss: -1.1304\n",
"iter: 40 Ground state energy: -1.1305 Ha\n", "iter: 40 Ground state energy: -1.1304 Ha\n",
"iter: 60 loss: -1.1358\n", "iter: 60 loss: -1.1363\n",
"iter: 60 Ground state energy: -1.1358 Ha\n", "iter: 60 Ground state energy: -1.1363 Ha\n",
"iter: 80 loss: -1.1370\n", "iter: 80 loss: -1.1372\n",
"iter: 80 Ground state energy: -1.1370 Ha\n", "iter: 80 Ground state energy: -1.1372 Ha\n",
"\n", "\n",
"训练后的电路:\n", "训练后的电路:\n",
"--Ry(4.702)----*--------------x----Ry(4.759)----*--------------x----Ry(0.001)--\n", "--Ry(1.572)----*--------------x----Ry(1.568)----*--------------x----Ry(0.012)--\n",
" | | | | \n", " | | | | \n",
"--Ry(-1.56)----x----*---------|----Ry(4.698)----x----*---------|----Ry(1.607)--\n", "--Ry(4.724)----x----*---------|----Ry(4.722)----x----*---------|----Ry(1.619)--\n",
" | | | | \n", " | | | | \n",
"--Ry(3.170)---------x----*----|----Ry(1.789)---------x----*----|----Ry(4.817)--\n", "--Ry(-0.03)---------x----*----|----Ry(4.954)---------x----*----|----Ry(-0.41)--\n",
" | | | | \n", " | | | | \n",
"--Ry(6.365)--------------x----*----Ry(1.562)--------------x----*----Ry(3.178)--\n", "--Ry(4.288)--------------x----*----Ry(1.564)--------------x----*----Ry(3.137)--\n",
" \n" " \n"
] ]
} }
...@@ -418,12 +418,12 @@ ...@@ -418,12 +418,12 @@
"metadata": {}, "metadata": {},
"source": [ "source": [
"### 测试效果\n", "### 测试效果\n",
"我们现在已经完成了量子神经网络的训练,通过 VQE 得到的基态能量的估计值大致为 $E_0 \\approx -1.137$ Ha,这与通过全价构型相互作用(FCI)$E_0 = -1.13728$ Ha 计算得出的值是在化学精度 $\\varepsilon = 1.6 \\times 10^{-3}$ Ha 内相符合的。" "我们现在已经完成了量子神经网络的训练,通过 VQE 得到的基态能量的估计值大致为 $E_0 \\approx -1.137$ Ha,这与通过 `Psi4` 在 sto-3g 基底下使用 FCI (full configuration-interaction) 方法计算得到的基态能量值 $E_0 = -1.13728$ Ha 是在化学精度 $\\varepsilon = 1.6 \\times 10^{-3}$ Ha 内相符合的。"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 7, "execution_count": 8,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:14:21.341323Z", "end_time": "2021-04-30T09:14:21.341323Z",
...@@ -433,14 +433,12 @@ ...@@ -433,14 +433,12 @@
"outputs": [ "outputs": [
{ {
"data": { "data": {
"image/png": "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ddLT08nJyWH37t3s3r2bYcOGAfDLX/6SDz74wO/zU1NTmTBhAmPHji1brrW83NxcLr30UvLy8jh06FCF603Mnz+f1T6Dcvfs2cO+ffto1qxZ2X1z584lKyuL6dOnA1BQUMD69euJiYlh0KBBdO7cGYC0tDRycnLKFnwaPXo04EokCQkJZce79FJXsbJ792727t3LkCFDALjiiiv417/+BcD48eO57777ePTRR3nllVdqZZnWUCWK9qqa593+EWgfaGcRGQTEAN9V8PivgV8DdOnSpRbD9IweDU89Bd98Az171v7xjQmCBx88cjs6+ujtRo2O3m7a9OjtFi2O3m51TOXwsfr06VP2xQ/w7LPPsmPHDjIyMnzO07TS40RHR1NSUlK27buoUKNGjcpuR0VFlVU9VeSqq67i66+/pmPHjsyZM4fZs2fzySefMGvWLB544AFWrlx5zHNuuukmbrvtNi688EIWLVrElClT/B67pKSEL7744pgFlXypKk8//TRnn332UfcvWrTomL/l8OHDqCp9+vThP//5j9/jVeX1a9KkCaNHj2bmzJm88847Aee3qqqgtVGIyHwRWeXnctTk7V6RRwMcJwF4E7hKVUv87aOqL6pqhqpmtG3btlb/DgBOP939Z1mjtjEVGjFiBIWFhTz33HNl9/30008V7j906FCmTp0KuC/ONm3a0KJFCxITE1m2bBkAy5YtY2Mlg17j4uKIi4srW0+i9JgAr776KsuXL2fOnDmUlJSwefNmzjzzTB5++GEKCgrYt28fzZs3Z+/evWXPKSgooFOnTgC8/vrrZfeX3++ss87i6aefLtv2bRcodfbZZ/Pcc89RVFQEwDfffMP+/fsr/Ft69uzJ9u3byxJFUVER2dnZfv/m5s2b8+WXXwIwbdq0ox6/5ppruPnmmxk4cCCtqpLlKxG0RKGqo1Q1xc9lJrDVSwCliWCbv2OISAtgNvC/qvpFsGKtVOPGLll88olNPW5MBUSE9957j48//pikpCQGDRrExIkTefjhh/3uP2XKFJYuXUpqaiqTJ08u+1K++OKLyc/Pp0+fPjzzzDNVmmL81Vdf5YYbbiAtLa2sUbi84uJifvGLX9C3b1/69+/PzTffTFxcHBdccAEzZswoa6SeMmUK48ePJz09nTZt2pQ9v/x+Tz31FJmZmaSmptK7d2+ef/75Y855zTXX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\n", "image/png": "iVBORw0KGgoAAAANSUhEUgAAAksAAAGwCAYAAAC5ACFFAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAAA9hAAAPYQGoP6dpAABgnklEQVR4nO3deVxUVeMG8OcOy7CDArIosrjihoppqKWvUu5LmUsv5ZrWm5aaWZqllq9ppVaaabaI/dJXW9zK0swtF9xQ3MENxQVEQ0FA1jm/P44zMAIj4AwDw/P9fO6H4c65957LwPDMOeeeqwghBIiIiIioWCpzV4CIiIioMmNYIiIiIjKAYYmIiIjIAIYlIiIiIgMYloiIiIgMYFgiIiIiMoBhiYiIiMgAa3NXwBJoNBpcv34dzs7OUBTF3NUhIiKiUhBC4O7du/D19YVKVXL7EcOSEVy/fh1+fn7mrgYRERGVw5UrV1CnTp0Sn2dYMgJnZ2cA8oft4uJi5toQERFRaaSlpcHPz0/3f7wkDEtGoO16c3FxYVgiIiKqYh42hIYDvImIiIgMYFgiIiIiMoBhiYiIiMgAjlkiIrJwGo0GOTk55q4GUYWzsbGBlZXVI++HYYmIyILl5OQgPj4eGo3G3FUhMgs3Nzd4e3s/0jyIDEtERBZKCIHExERYWVnBz8/P4KR7RJZGCIHMzEwkJycDAHx8fMq9L4YlIiILlZeXh8zMTPj6+sLBwcHc1SGqcPb29gCA5ORk1KpVq9xdcvyYQURkofLz8wEAtra2Zq4JkfloPyjk5uaWex8MS0REFo73rKTqzBi//wxLRERERAYwLBEREREZwLBEREREZADDUmV2+zaQmAhwMjkiIiKzYViqzN54AxgzBrh82dw1ISIyi0WLFuH69etl2uaff/5BrVq1cOnSJd06IQQWLFiAwMBAODg4oH///khNTdU9P2TIEMyfP19vPzt37kRAQEC56v0o2xZXf8DwORRXfwD47rvvEBsbW656UAGGpcpMe7kvW5aIqBo6f/483n77bdSoUaNM282ePRv9+vXTCyuTJ0/GkiVLsGLFCuzevRvR0dGYOXOm7vl3330Xs2fP1gtQJenUqRNGjhxZZP2XX34JJyenR54tvbj6P+wcSqr/gQMH8NVXXz1SfYhhqXJjWCIiYxICyMoyzyJEmau7YcMGPPXUU7qJBUsjMzMT3377LUaNGqVbd+DAASxYsABr1qzBk08+idDQUIwePRq///67rkyzZs1Qr149/PDDDw/5EQocPXoUoaGhRZ47fPgwWrZs+UgzpRdX/9KcQ0n179evHzZu3Fju+pDEGbwrM7VafmVYIiJjyM4GBg40z7F/+gmwsyvTJhs2bMCwYcN0369fvx4jRozA7du3ceHCBdSvXx+JiYnw8PCAs7Mz1q1bh/T0dKjVajz++OO67ebNm4euXbuidevWunVeXl64deuW3vH69OmD1atXY+zYsSXW6dy5c7h7926JYelf//pXiduWt/6lPYfi6t+1a1fcuHEDJ0+eRLNmzUqsGxnGlqXKTNuylJ1t3noQEVWwW7duYf/+/ejdu7duXUxMDEJCQgAAx44dg5eXF7y9vREbG4usrCy0bNkSu3fv1gsy2dnZ2LRpE5555hm9/WdlZcHV1VVvXdu2bXHw4EFkG3jPjY6OhpWVla4eWvfu3cPp06f1wsyDylP/spxDcfVXq9V4+umn2br0iNiyVJmxG46IjEmtli085jp2Gfz2229o06YNvLy8dOuOHTumFzaKCx6XL1+Gr6+vbpsjR47g3r17mDRpEt566y3d+tzc3CKtQL6+vsjJyUFSUhL8/f2LrdeRI0eQn59f4r32DIWl8tS/LOdQUv379euHJUuW4J133imxbmQYw1Jlxm44IjImRSlzV5i5/P777+jZs6feupiYGPTp0weAftiIiYlBy5YtAcgWHrtC53j27Fk4OjoiJiZGb1+9evVChw4d9NZpx0ZlZmaWWK8jR47gmWeewfTp0/XWr169GgsXLkSTJk1K3LY89S/LOZRU/549e2LEiBG4desWPDw8Sqwflcwiu+EWL16MgIAA2NnZoV27djh48KDB8j/99BMaN24MOzs7NG/eXG/Qn1mxG46IqqmAgADEx8frvk9LS8OlS5d0424Kh40jR46gVatWAAAPDw/cvn1bbzsPDw/Ur19ft9jY2ODcuXMYMGCA3jFTUlIAAJ6eniXW68iRI+jcuTNatmypt6SkpKBFixYl3tW+vPUvyzmUVP/4+Hi4ubnBzc2txPMiwywuLK1ZswZvvPEGZsyYgSNHjiAkJATdunVDcnJyseX37duH559/HqNGjcLRo0fRv39/9O/fHydPnqzgmheDLUtEVE3169cPmzZt0l2Gn5iY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\n",
"text/plain": [ "text/plain": [
"<Figure size 432x288 with 1 Axes>" "<Figure size 640x480 with 1 Axes>"
] ]
}, },
"metadata": { "metadata": {},
"needs_background": "light"
},
"output_type": "display_data" "output_type": "display_data"
} }
], ],
...@@ -469,7 +467,7 @@ ...@@ -469,7 +467,7 @@
" r'\\right|H\\left| {\\psi \\left( {\\theta } \\right)} \\right\\rangle $',\n", " r'\\right|H\\left| {\\psi \\left( {\\theta } \\right)} \\right\\rangle $',\n",
" 'Ground-state energy',\n", " 'Ground-state energy',\n",
" ], loc='best')\n", " ], loc='best')\n",
"\n", "plt.text(-15.5, -1.145, f'{min_eig_H:.5f}', fontsize=10, color='b')\n",
"#plt.savefig(\"vqe.png\", bbox_inches='tight', dpi=300)\n", "#plt.savefig(\"vqe.png\", bbox_inches='tight', dpi=300)\n",
"plt.show()" "plt.show()"
] ]
...@@ -484,7 +482,7 @@ ...@@ -484,7 +482,7 @@
"\n", "\n",
"![vqe-fig-dist](figures/vqe-fig-distance.png)\n", "![vqe-fig-dist](figures/vqe-fig-distance.png)\n",
"\n", "\n",
"从上图可以看出,最小值确实发生在 $d = 74$ pm (1 pm = $1\\times 10^{-12}$m) 附近,这是与[实验测得数据](https://cccbdb.nist.gov/exp2x.asp?casno=1333740&charge=0)相符合的 $d_{exp} (H_2) = 74.14$ pm." "从上图可以看出,最小值确实发生在 $d = 74$ pm (1 pm = $1\\times 10^{-12}$ m) 附近,这是与[实验测得数据](https://cccbdb.nist.gov/exp2x.asp?casno=1333740&charge=0)相符合的 $d_{exp} (H_2) = 74.14$ pm."
] ]
}, },
{ {
...@@ -530,7 +528,7 @@ ...@@ -530,7 +528,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.8.10" "version": "3.8.0"
}, },
"toc": { "toc": {
"base_numbering": 1, "base_numbering": 1,
......
...@@ -109,7 +109,7 @@ ...@@ -109,7 +109,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 1, "execution_count": 8,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:14:44.970178Z", "end_time": "2021-04-30T09:14:44.970178Z",
...@@ -144,7 +144,7 @@ ...@@ -144,7 +144,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 2, "execution_count": 9,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:14:44.982005Z", "end_time": "2021-04-30T09:14:44.982005Z",
...@@ -156,24 +156,24 @@ ...@@ -156,24 +156,24 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"FCI energy for H2_sto-3g_singlet (2 electrons) is -1.137283834485513.\n", "FCI energy for H2_sto-3g_singlet (2 electrons) is -1.1372838344855134.\n",
"\n", "\n",
"The generated h2 Hamiltonian is \n", "The generated h2 Hamiltonian is \n",
" -0.09706626861762556 I\n", " -0.0970662686176252 I\n",
"-0.04530261550868938 X0, X1, Y2, Y3\n", "-0.04530261550868938 X0, X1, Y2, Y3\n",
"0.04530261550868938 X0, Y1, Y2, X3\n", "0.04530261550868938 X0, Y1, Y2, X3\n",
"0.04530261550868938 Y0, X1, X2, Y3\n", "0.04530261550868938 Y0, X1, X2, Y3\n",
"-0.04530261550868938 Y0, Y1, X2, X3\n", "-0.04530261550868938 Y0, Y1, X2, X3\n",
"0.1714128263940239 Z0\n", "0.1714128263940238 Z0\n",
"0.16868898168693286 Z0, Z1\n", "0.16868898168693292 Z0, Z1\n",
"0.12062523481381837 Z0, Z2\n", "0.12062523481381847 Z0, Z2\n",
"0.16592785032250773 Z0, Z3\n", "0.1659278503225078 Z0, Z3\n",
"0.17141282639402394 Z1\n", "0.17141282639402383 Z1\n",
"0.16592785032250773 Z1, Z2\n", "0.1659278503225078 Z1, Z2\n",
"0.12062523481381837 Z1, Z3\n", "0.12062523481381847 Z1, Z3\n",
"-0.2234315367466399 Z2\n", "-0.22343153674664024 Z2\n",
"0.17441287610651626 Z2, Z3\n", "0.17441287610651632 Z2, Z3\n",
"-0.2234315367466399 Z3\n" "-0.2234315367466403 Z3\n"
] ]
} }
], ],
...@@ -195,7 +195,7 @@ ...@@ -195,7 +195,7 @@
"molecular_hamiltonian = qchem.spin_hamiltonian(molecule=molecule,\n", "molecular_hamiltonian = qchem.spin_hamiltonian(molecule=molecule,\n",
" filename=None, \n", " filename=None, \n",
" multiplicity=1, \n", " multiplicity=1, \n",
" mapping_method = 'jordan_wigner',)\n", " mapping_method='jordan_wigner',)\n",
"# Print results\n", "# Print results\n",
"print(\"\\nThe generated h2 Hamiltonian is \\n\", molecular_hamiltonian)" "print(\"\\nThe generated h2 Hamiltonian is \\n\", molecular_hamiltonian)"
] ]
...@@ -226,7 +226,7 @@ ...@@ -226,7 +226,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 11, "execution_count": 10,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:14:50.083041Z", "end_time": "2021-04-30T09:14:50.083041Z",
...@@ -277,7 +277,7 @@ ...@@ -277,7 +277,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 12, "execution_count": 11,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:14:50.183996Z", "end_time": "2021-04-30T09:14:50.183996Z",
...@@ -319,7 +319,7 @@ ...@@ -319,7 +319,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 13, "execution_count": 12,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:14:50.222465Z", "end_time": "2021-04-30T09:14:50.222465Z",
...@@ -345,7 +345,7 @@ ...@@ -345,7 +345,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 14, "execution_count": 13,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:15:52.165788Z", "end_time": "2021-04-30T09:15:52.165788Z",
...@@ -357,23 +357,23 @@ ...@@ -357,23 +357,23 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"iter: 20 loss: -1.0510\n", "iter: 20 loss: -1.0487\n",
"iter: 20 Ground state energy: -1.0510 Ha\n", "iter: 20 Ground state energy: -1.0487 Ha\n",
"iter: 40 loss: -1.1298\n", "iter: 40 loss: -1.1070\n",
"iter: 40 Ground state energy: -1.1298 Ha\n", "iter: 40 Ground state energy: -1.1070 Ha\n",
"iter: 60 loss: -1.1361\n", "iter: 60 loss: -1.1152\n",
"iter: 60 Ground state energy: -1.1361 Ha\n", "iter: 60 Ground state energy: -1.1152 Ha\n",
"iter: 80 loss: -1.1371\n", "iter: 80 loss: -1.1165\n",
"iter: 80 Ground state energy: -1.1371 Ha\n", "iter: 80 Ground state energy: -1.1165 Ha\n",
"\n", "\n",
"Circuit after training:\n", "Circuit after training:\n",
"--Ry(4.710)----*--------------x----Ry(1.569)----*--------------x----Ry(-0.01)--\n", "--Ry(4.725)----*--------------x----Ry(-0.01)----*--------------x----Ry(-1.56)--\n",
" | | | | \n", " | | | | \n",
"--Ry(1.507)----x----*---------|----Ry(1.566)----x----*---------|----Ry(4.392)--\n", "--Ry(4.718)----x----*---------|----Ry(3.132)----x----*---------|----Ry(4.703)--\n",
" | | | | \n", " | | | | \n",
"--Ry(5.984)---------x----*----|----Ry(4.476)---------x----*----|----Ry(1.692)--\n", "--Ry(4.720)---------x----*----|----Ry(3.124)---------x----*----|----Ry(4.721)--\n",
" | | | | \n", " | | | | \n",
"--Ry(0.132)--------------x----*----Ry(7.773)--------------x----*----Ry(3.194)--\n", "--Ry(1.574)--------------x----*----Ry(6.291)--------------x----*----Ry(1.552)--\n",
" \n" " \n"
] ]
} }
...@@ -424,13 +424,12 @@ ...@@ -424,13 +424,12 @@
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Benchmarking\n", "### Benchmarking\n",
"We have now completed the training of the quantum neural network, and the estimated value of the ground state energy obtained is $E_0 \\approx -1.137 $ Hartree, we compare it with the theoretical value $E_0 = -1.1371$ to benchmark our model. The estimation obtained with VQE agree with a full configuration-interaction (FCI) calculation within chemical accuracy $\\varepsilon = 1.6 \\times 10^{-3}$ Hartree.\n", "We have now completed the training of the quantum neural network, and the estimated value of the ground state energy obtained is $E_0 \\approx -1.137 $ Hartree. The estimation obtained with VQE is consistent with the value of the ground state energy $E_0 = -1.13728$ Hartree calculated by `Psi4` at sto-3g basis using the full configuration-interaction (FCI) method within the chemical accuracy $\\varepsilon = 1.6 \\times 10^{-3}$ Hartree.\n"
"\n"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 15, "execution_count": 14,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-04-30T09:15:18.096944Z", "end_time": "2021-04-30T09:15:18.096944Z",
...@@ -440,14 +439,12 @@ ...@@ -440,14 +439,12 @@
"outputs": [ "outputs": [
{ {
"data": { "data": {
"image/png": "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DhNgjDnaTTfdxGeffUZMTEzhrHADBw6kYcOGAHz22We8/fbbAPTr14/t27ezu4QLSZKSkgpnnktPTycrK4udO3eyc+dO+vTpA8BvfvMbPvjgg6DPT0lJYcSIEQwZMqRwutaisrOzGT58OBs3biQvL6/Y+SZmzpzJ8uXLC9d3797N3r17qVu3buG2GTNmsHjxYiZOnAjArl27WLNmDTExMXTr1o2WLVsCkJaWRlZWVuGETwMHDgTcGUnz5s0L9zd8+HAAdu7cyZ49e+jZsycAv/71r3nvvfcAGDZsGPfeey8PP/wwL730Urn0TrdEUZSN92SqiPvv/2U5OvrI9djYI9fj4o5cT0g4cr1Bg5KPl5ycXPjFD/DUU0+xbds2MjIyAo4TV+J+oqOjOXz4cOF64KRCsbGxhctRUVGFVU/Fufrqq/n222858cQTmTZtGu+//z6ffvopU6dO5e9//ztLliw56jk333wzt912GxdddBFz5sxh3LhxQfd9+PBhvvrqq6MmVAqkqjzxxBOcc845R2yfM2fOUX/LoUOHUFWSk5P58ssvg+6vNK9fnTp1GDhwIJMnT+att94KOb5VaVWJy2PLlY0ga8xx6devH7m5uTz99NOF2/bv319s+d69ezN+/HjAfXE2btyYhIQEEhMTWbBgAQALFixg3bp1IY9bv3596tevXzifRME+AV5++WUWLlzItGnTOHz4MBs2bKBv3748+OCD7Nq1i7179xIfH8+egP/3Xbt20aKF69L16quvFm4vWu7ss8/miSeeKFwPbBcocM455/D0009z8OBBAFavXs2+ffuK/VtOPfVUtm7dWpgoDh48yLJly4L+zfHx8Xz99dcATJgw4YjHR40axS233ELXrl1pUJosXwJLFEXZeE/GHBcR4d133+WTTz4hKSmJbt26MXLkSB58MPjIO+PGjWP+/PmkpKQwduzYwi/lSy+9lJycHJKTk3nyySdLNcT4yy+/zE033URaWlpho3BR+fn5XHHFFXTq1InOnTtzyy23UL9+fS688EImTZpU2Eg9btw4hg0bRnp6Oo0bNy58ftFyjz/+OJmZmaSkpNChQweeeeaZo445atQoOnToQJcuXejYsSO//e1vQ16xFBMTw8SJE7nzzjtJTU0lLS2t2CutXnzxRa677jrS0tLYt28f9erVK3wsPT2dhIQErr766hJf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\n", "image/png": "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MamiGJaqM3VYSk83bh1ERFUsKCgIQgicOnUKAFC3bl3Y2dlh2bJlOHToEKytrZGZmYnnn38egYGBePbZZwEAvXv3xuXLlzW9M88++yyysrKwcOFCREdH49///jd+/fVXrF69utgxjxw5gueee67UmsLDw2FhYaG5ZKaWm5uLS5cu6RyvVNH6y3MOpdW/c+dODB48uNTa6PEYlqozdVhKTTVuHUREVczCwgIDBgzAjh07AACOjo746aefcODAAQwZMgS5ubno27cvunTpgt27d0OhUAAAWrdujQ4dOuCnn34CIL9ev27dOqxevRotW7bEyZMncfToUfj6+modLysrC9u3b8eECRNKrens2bNo0qQJHNW/m//flStXkJ2drTMsVbT+sp5DafVHR0cjMjISffr0KbU2KgNBlZacnCwAiOTkZP3u+PZtIQYMEGLkSP3ul4hqhMzMTHHlyhWRmZlp7FIqZMeOHSIgIKBY+0svvSReeukloVKpStxu165dIiAgQOTn55f5WF999ZXo1auXVtvBgweFn59fuWouy7ZVVb8QQixfvlw899xzZd6POdL130FZ/36zZ6k6U9/uJD29QrPfEhGZsl69eiEmJgY3b97Uao+MjERgYKCmN6ao/v37Y+LEibh7926Zj2VtbY2VK1dWqt6yqsr6d+7ciUGDBlW4VpI42qs6U3f1CgFkZBSEJyKiGsDOzg7pRcZs5uXl4fLly8XGDRU1bdq0ch3r1VdfLWd1FVPV9e/fv79c+6GSMSxVZzY2csnJkd+IY1giohrOysoKWVlZVXIsf3//coeWx21blfWT/vAyXHXH6QOIiIzCEGGJTBPDUnXHsERERGRUDEvVHcMSERGRUTEsVXcMS0REREbFsFTdMSwREREZFcNSdcewREREZFQMS9UdwxIREZFRMSxVdwxLREQmY+7cuY+dcJJMD8NSdcewREQ1UHx8PKZOnYrGjRvD1tYWnp6e6Nq1K1avXo2MjAxjl2cwY8aMwZAhQ8q9HUOaYXEG7+qOYYmIapi///4bXbt2haurKz799FO0bt0aSqUSFy9exDfffIO6deuWer+z3NxcWFtbV3HFVFn5+flQKBSwsKiefTjVsyoqwLBERDXMG2+8ASsrK5w5cwbDhw9HQEAAGjZsiMGDB2P37t0YOHCgZl2FQoHVq1dj0KBBcHBwwIIFCwAA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p6drAtmxY8dgYWFR7PMlIokDvInosVq3bo2QkBCsWLFCq71Hjx64f/8+PvvsM0RFRWHVqlX4/fff9XbcVatWYdu2bbh27RomT56MR48eYdy4cQCAyZMnIzExES+99BJOnz6NqKgo7N27F2PHjn1sYChq5syZWLRoETZv3ozIyEjMmjULERERmDp1aqXq9/f3x19//YW7d+9qvqX33nvv4fjx45gyZQoiIiJw48YN7Nixo9gA66KaNGmC27dvY9OmTYiKisKKFSuwbdu2YseLjo5GREQEHjx4gOzs7GL7CQkJga2tLUaPHo1Lly7h4MGDePPNN/Gvf/1LcwmOiLQxLBFRmXzyySfFLsMEBATgq6++wqpVq9C2bVuEhYVVamxTUQsXLsTChQvRtm1bHD16FDt37kSdOnUAQNMblJ+fj+eeew6tW7fGtGnT4OrqqjU+qizeeustvP3225gxYwZat26NPXv2YOfOnWjSpEml6v/kk09w69YtNGrUCO7u7gCANm3a4PDhw7h+/TqeeuoptG/fHh9//DF8fHx07mvQoEGYPn06pkyZgnbt2uH48eOab8mpDR06FH369MEzzzwDd3d3/O9//yu2H3t7e+zduxeJiYl44okn8OKLL6Jnz5748ssvK3WuROZMIYoOOCAiIiIiDfYsEREREenAsERERESkA8MSERERkQ4MS0REREQ6MCwRERER6cCwRERERKQDwxIRERGRDgxLRERERDowLBERERHpwLBEREREpAPDEhEREZEO/wcgLtckls/ftwAAAABJRU5ErkJggg==",
"text/plain": [ "text/plain": [
"<Figure size 432x288 with 1 Axes>" "<Figure size 640x480 with 1 Axes>"
] ]
}, },
"metadata": { "metadata": {},
"needs_background": "light"
},
"output_type": "display_data" "output_type": "display_data"
} }
], ],
...@@ -476,7 +473,7 @@ ...@@ -476,7 +473,7 @@
" r'\\right|H\\left| {\\psi \\left( {\\theta } \\right)} \\right\\rangle $',\n", " r'\\right|H\\left| {\\psi \\left( {\\theta } \\right)} \\right\\rangle $',\n",
" 'Ground-state energy',\n", " 'Ground-state energy',\n",
" ], loc='best')\n", " ], loc='best')\n",
"\n", "plt.text(-15.5, -1.145, f'{min_eig_H:.5f}', fontsize=10, color='b')\n",
"#plt.savefig(\"vqe.png\", bbox_inches='tight', dpi=300)\n", "#plt.savefig(\"vqe.png\", bbox_inches='tight', dpi=300)\n",
"plt.show()" "plt.show()"
] ]
...@@ -535,7 +532,7 @@ ...@@ -535,7 +532,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.8.10" "version": "3.8.0"
}, },
"toc": { "toc": {
"base_numbering": 1, "base_numbering": 1,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册