From 7be2573599d0420032a95ddf6459f533cbd4eb1f Mon Sep 17 00:00:00 2001 From: he-tianshen Date: Mon, 24 Jan 2022 19:44:42 +0800 Subject: [PATCH 1/2] 6_hw08624896/ --- paper_recurrence/6_hw08624896/main.ipynb | 989 ++++++++++++++++++ paper_recurrence/6_hw08624896/readme.md | 15 + .../6_hw08624896/src/accvqeexact.py | 55 + .../6_hw08624896/src/layer recursive.py | 111 ++ .../6_hw08624896/src/qubit recursive.py | 219 ++++ .../6_hw08624896/src/random initialization.py | 105 ++ paper_recurrence/6_hw08624896/src/readme.md | 1 + 7 files changed, 1495 insertions(+) create mode 100644 paper_recurrence/6_hw08624896/main.ipynb create mode 100644 paper_recurrence/6_hw08624896/readme.md create mode 100644 paper_recurrence/6_hw08624896/src/accvqeexact.py create mode 100644 paper_recurrence/6_hw08624896/src/layer recursive.py create mode 100644 paper_recurrence/6_hw08624896/src/qubit recursive.py create mode 100644 paper_recurrence/6_hw08624896/src/random initialization.py create mode 100644 paper_recurrence/6_hw08624896/src/readme.md diff --git a/paper_recurrence/6_hw08624896/main.ipynb b/paper_recurrence/6_hw08624896/main.ipynb new file mode 100644 index 000000000..45d8c6c0f --- /dev/null +++ b/paper_recurrence/6_hw08624896/main.ipynb @@ -0,0 +1,989 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Accelerated variational algorithms for digital quantum simulation of the many-body ground states\n", + "\n", + "## 项目介绍" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "论文的目标是在数字量子模拟器(Digital Quantum Simulator, DQS)上制备一维链海森堡模型的基态(开放边界条件)$$H=J \\sum_{i=1}^{N-1} \\sigma^{i} \\cdot \\sigma^{i+1}$$\n", + "其中$J$为exchange coupling,是大于0的实数,$\\sigma^{i}=\\left(\\sigma_{x}^{i}, \\sigma_{y}^{i}, \\sigma_{z}^{i}\\right)$是第$i$个qubit上的Pauli算符组成的向量。\n", + "\n", + "### 一、绝热演化\n", + "针对此目标,论文首先提出了使用Suzuki-Trotter expansion来模拟绝热演化的方案,即进行如下的绝热演化$$H_{a d}(t)=H_{o d d}+\\frac{t}{T_{\\max }} H_{e v e n}$$\n", + "其中$H_{o d d}=J \\sum_{\\text {odd } i} \\sigma^{i} \\cdot \\sigma^{i+1}$,$H_{\\text {even }}=J \\sum_{\\text {even } i} \\sigma^{i} \\cdot \\sigma^{i+1}$,$0 \\leq t \\leq T_{\\max }$,$H_{o d d}$的基态是容易制备的$$|\\Psi(0)\\rangle=\\left|\\psi^{-}\\right\\rangle \\otimes \\cdots \\otimes\\left|\\psi^{-}\\right\\rangle$$其中$\\left|\\psi^{-}\\right\\rangle=(|01\\rangle-|10\\rangle) / \\sqrt{2}$\n", + "\n", + "当取$T_{\\max } \\sim N^{2}$时,就能满足绝热定理的条件,并且$t=T_{\\max }$时$H_{a d}\\left(T_{\\max }\\right)=H$\n", + "\n", + "实现绝热演化的线路图见论文Fig.1\n", + "\n", + "### 二、VQE\n", + "实现绝热演化的线路深度过高,考虑使用VQE,以在保障精度的同时降低线路深度。绝热演化的严格性由物理定律保证,因此在设计VQE所使用的参数化量子线路(Parameterized Quantum Circuit, PQC)时,论文借鉴了绝热演化的线路结构。VQE的线路图见论文Fig.3\n", + "\n", + "在此基础上,论文对如何缩短VQE参数更新的经典优化循环次数作了进一步的讨论,提出了3种策略。\n", + "#### 1. 随机初始化\n", + "#### 2. 比特数递归\n", + "#### 3. 层数递归\n", + "策略的具体内容在复现过程中详细介绍。\n", + "\n", + "### 三、其他讨论\n", + "论文最后讨论了以下四点:\n", + "#### 1. 线路的扩展性\n", + "相同的线路可以扩展到各向异性的海森堡模型,只需要门参数做一些微调,不用引入新的参数。\n", + "#### 2. 镜面对称性的作用\n", + "文中使用的PQC线路的结构中,每一层的PQC最后都有一层所有qubit上的相位门。由于论文中考虑的哈密顿量具有镜面对称性,在前文的讨论中,这一层相位门的参数也被强加了这一对称性。但作者发现,倘若取消相位门的镜面对称性,VQE反而能以更快的速度收敛。\n", + "#### 3. VQE线路设计思路\n", + "作者提出,VQE线路借鉴绝热演化的Suzuki-Trotter expansion这一思路是普适的。\n", + "#### 4. 退相干的影响\n", + "将线路固定为某一次VQE的最终参数,引入双量子比特门的随机的噪声扰动或失相,考察对保真度的影响。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 复现过程" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "首先,安装、导入依赖包。" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!pip install https://hiq.huaweicloud.com/download/mindquantum/newest/linux/mindquantum-master-cp37-cp37m-linux_x86_64.whl -i https://pypi.tuna.tsinghua.edu.cn/simple" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from mindquantum import Circuit, X, H, RZ, RY, PhaseShift, Hamiltonian, Simulator, QubitOperator, Hamiltonian, MQAnsatzOnlyLayer\n", + "import mindspore as ms\n", + "from mindspore.common.parameter import Parameter\n", + "import mindspore.context as context\n", + "\n", + "context.set_context(mode=context.PYNATIVE_MODE, device_target=\"CPU\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "参考Fig.1a,自定义一个单参数双量子比特门N(论文中的$\\mathcal{N}(\\theta)$),这个门使用参数f'p{count}',作用于 i 和 i + 1 号量子比特(也即第$i+1$和第$i+2$个量子比特)。" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "def N(count, i):\n", + " temp = Circuit()\n", + " temp += RZ(np.pi / 2).on(i + 1)\n", + " temp += X.on(i, i + 1)\n", + " temp += RZ({f'p{count}' : 2}).on(i)\n", + " temp += RZ(-np.pi / 2).on(i)\n", + " temp += RY(np.pi / 2).on(i + 1)\n", + " temp += RY({f'p{count}' : -2}).on(i + 1)\n", + " temp += X.on(i + 1, i)\n", + " temp += RY({f'p{count}' : 2}).on(i + 1)\n", + " temp += RY(-np.pi / 2).on(i + 1)\n", + " temp += X.on(i, i + 1)\n", + " temp += RZ(-np.pi / 2).on(i)\n", + " return temp" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Strategy 1: random initialization." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "定义模型的量子比特数num(论文中的$N$),和VQE线路的层数m(论文中的$M_{VQE}$)。根据论文Table.1,$N$取$4,8,10$时,若要达到$F=0.99$保真度,$M_{VQE}$应分别取$2,3,3$. 由于本文考虑哈密顿量的镜面对称性,因此要求$N$必须是偶数。" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4 2\n" + ] + } + ], + "source": [ + "NMtable = {4:2, 8:3, 10:3, 16:5, 20:6}\n", + "num = 4\n", + "m = NMtable[num]\n", + "assert num % 2 == 0\n", + "print(num, m)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "制备初态$|\\Psi(0)\\rangle=\\left|\\psi^{-}\\right\\rangle \\otimes \\cdots \\otimes\\left|\\psi^{-}\\right\\rangle$,其中$\\left|\\psi^{-}\\right\\rangle=(|01\\rangle-|10\\rangle) / \\sqrt{2}$,这个量子态是$H_{o d d}=J \\sum_{\\operatorname{odd} i} \\sigma^{i} \\cdot \\sigma^{i+1}$的基态,如前文所述,是绝热演化的起点,因此也是参数化量子线路的起点。" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "q0: ──X────H────●──\n", + " │\n", + "q1: ──X─────────X──\n", + "\n", + "q2: ──X────H────●──\n", + " │\n", + "q3: ──X─────────X──\n", + "=======Circuit Summary=======\n", + "|Total number of gates : 8.|\n", + "|Parameter gates : 0.|\n", + "|with 0 parameters are : . |\n", + "|Number qubit of circuit: 4 |\n", + "=============================\n" + ] + } + ], + "source": [ + "encoder = Circuit()\n", + "for i in range(0, num, 2):\n", + " encoder += X.on(i)\n", + " encoder += X.on(i + 1)\n", + " encoder += H.on(i)\n", + " encoder += X.on(i + 1, i)\n", + " \n", + "print(encoder)\n", + "encoder.summary()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "参考Fig.3a构建ansatz线路,由于encoder中不含有参数,最后直接将其与ansatz合并。" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "q0: ──X────H────●───────────────X────RZ(2*p1)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)─────PS(p4)──────────────────────────────────────────────────────────────────────────────────────────────────────────X────────RZ(2*p6)─────RZ(-π/2)───────●───────────────────────────────────X───────RZ(-π/2)─────PS(p9)─────────────────────────────────────────────────────────────────────────\n", + " │ │ │ │ │ │ │\n", + "q1: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p1)────X────RY(2*p1)────RY(-π/2)────●───────────────────────────X────RZ(2*p3)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────PS(p5)────RZ(π/2)─────────●────────RY(π/2)─────RY(-2*p6)───────X────────RY(2*p6)────RY(-π/2)───────●──────────X────────RZ(2*p8)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────PS(p10)──\n", + " │ │ │ │ │ │\n", + "q2: ──X────H────●───────────────X────RZ(2*p2)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────RZ(π/2)────●────RY(π/2)─────RY(-2*p3)────X────RY(2*p3)────RY(-π/2)────●────PS(-p5)───────X───────RZ(2*p7)─────RZ(-π/2)───────●────────────────────────────────────X────────RZ(-π/2)────RZ(π/2)───────●────────RY(π/2)─────RY(-2*p8)────X────RY(2*p8)────RY(-π/2)────●────PS(-p10)─────────────\n", + " │ │ │ │ │ │ │\n", + "q3: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p2)────X────RY(2*p2)────RY(-π/2)────●────PS(-p4)─────RZ(π/2)──────────────────────────────────────────────────────────────────────────────────●───────RY(π/2)─────RY(-2*p7)───────X─────────RY(2*p7)────RY(-π/2)───────●────────PS(-p9)────────────────────────────────────────────────────────────────────────────────────────────────────────────\n", + "==========================Circuit Summary==========================\n", + "|Total number of gates : 82. |\n", + "|Parameter gates : 26. |\n", + "|with 10 parameters are : p1, p2, p3, p4, p5, p6, p7, p8, p9, p10.|\n", + "|Number qubit of circuit: 4 |\n", + "===================================================================\n" + ] + } + ], + "source": [ + "ansatz = Circuit()\n", + "count = 1\n", + "\n", + "for j in range(m):\n", + " for i in range(0, num - 1, 2):\n", + " ansatz += N(count, i)\n", + " count += 1\n", + " for i in range(1, num - 1, 2):\n", + " ansatz += N(count, i)\n", + " count += 1\n", + " for i in range(0, num // 2):\n", + " ansatz += PhaseShift('p%d' % count).on(i)\n", + " ansatz += PhaseShift({'p%d' % count : -1}).on(num - i - 1)\n", + " count += 1\n", + "\n", + "ansatz = encoder + ansatz\n", + "print(ansatz)\n", + "ansatz.summary()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "参考式(1),构建哈密顿量$H=J \\sum_{i=1}^{N-1} \\sigma^{i} \\cdot \\sigma^{i+1}$,这里定义$J=1$" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 [X0 X1] +\n", + "1 [Y0 Y1] +\n", + "1 [Z0 Z1] +\n", + "1 [X1 X2] +\n", + "1 [Y1 Y2] +\n", + "1 [Z1 Z2] +\n", + "1 [X2 X3] +\n", + "1 [Y2 Y3] +\n", + "1 [Z2 Z3] \n" + ] + } + ], + "source": [ + "J = 1\n", + "ham = QubitOperator('')\n", + "for i in range(num - 1):\n", + " ham += QubitOperator('X%d X%d' % (i, i + 1), J)\n", + " ham += QubitOperator('Y%d Y%d' % (i, i + 1), J)\n", + " ham += QubitOperator('Z%d Z%d' % (i, i + 1), J)\n", + "ham = Hamiltonian(ham - QubitOperator(''))\n", + "\n", + "print(ham)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "构建参数化量子线路,对参数进行随机初始化(标准正态分布)。" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Initial energy: -0.0997337326407433\n" + ] + } + ], + "source": [ + "val = np.random.randn(count - 1)\n", + "\n", + "sim = Simulator('projectq', num)\n", + "pqc = sim.get_expectation_with_grad(ham, ansatz)\n", + "pqcnet = MQAnsatzOnlyLayer(pqc)\n", + "pqcnet.weight = Parameter(ms.Tensor(val, pqcnet.weight.dtype))\n", + "\n", + "initial_energy = pqcnet()\n", + "print(\"Initial energy: %20.16f\" % (initial_energy.asnumpy()))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "使用Adam算法进行梯度优化,各参数取值如论文所述。当相邻两步的能量差小于阈值时(这里设定为1e-8),判定为收敛,更新结束。" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "eps: 1e-08\n", + "Step 0 energy -0.0997337326407433\n", + "Step 100 energy -5.9991140365600586\n", + "Step 200 energy -6.3746271133422852\n", + "Optimization completed at step 285\n", + "Optimized energy: -6.4641013145446777\n", + "Optimized amplitudes: \n", + " [ 0.4028975 1.7767195 0.78539985 -0.44342345 0.44359204 -0.23663777\n", + " 0.5444191 -0.54652977 -1.57108 -1.5708411 ]\n" + ] + } + ], + "source": [ + "optimizer = ms.nn.Adam(pqcnet.trainable_params(), learning_rate = 0.01, beta1 = 0.9, beta2 = 0.999, eps = 1e-8)\n", + "train_pqcnet = ms.nn.TrainOneStepCell(pqcnet, optimizer)\n", + "\n", + "eps = 1.e-8\n", + "print(\"eps: \", eps)\n", + "energy_diff = eps * 1000\n", + "energy_last = initial_energy.asnumpy() + energy_diff\n", + "iter_idx = 0\n", + "while (abs(energy_diff) > eps):\n", + " energy_i = train_pqcnet().asnumpy()\n", + " if iter_idx % 100 == 0:\n", + " print(\"Step %3d energy %20.16f\" % (iter_idx, float(energy_i)))\n", + " energy_diff = energy_last - energy_i\n", + " energy_last = energy_i\n", + " iter_idx += 1\n", + "\n", + "print(\"Optimization completed at step %3d\" % (iter_idx - 1))\n", + "print(\"Optimized energy: %20.16f\" % (energy_i))\n", + "print(\"Optimized amplitudes: \\n\", pqcnet.weight.asnumpy())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "使用accvqeexact.py求解哈密顿量严格对角化的结果,该程序输出一个实数表示基态能量,可以与VQE的结果进行对比。\\\n", + "N取4,8,10时,基态能量分别为-6.464101615137754, -13.499730394751591, -17.032140829131546." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Strategy 1完整源代码见src/random initialization.py" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Strategy 2: qubit recursive.\n", + "\n", + "这个策略先在较小的系统(目标尺寸的一半,可以递归至最小的大于等于4的偶数)上进行VQE,将此步得到的最终参数作为目标系统的VQE线路参数的初猜。在本文档中,为方便进行演示,以前文Strategy 1中尺寸的两倍作为目标尺寸,以前文的参数作为新线路参数的初猜。" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "8 3\n" + ] + } + ], + "source": [ + "num2 = 2 * num\n", + "m2 = NMtable[num2]\n", + "print(num2, m2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "构建大系统的ansatz和哈密顿量。" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "q0: ──X────H────●───────────────X────RZ(2*p1)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)─────PS(p8)─────────────────────────────────────────────────────────────────────────────────────────────────────────────X─────────RZ(2*p12)─────RZ(-π/2)────────●────────────────────────────────────X───────RZ(-π/2)─────PS(p19)───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────X─────────RZ(2*p23)─────RZ(-π/2)────────●─────────────────────────────────────X─────────RZ(-π/2)──────PS(p30)───────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n", + " │ │ │ │ │ │ │ │ │ │\n", + "q1: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p1)────X────RY(2*p1)────RY(-π/2)────●───────────────────────────X────RZ(2*p5)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)─────PS(p9)──────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p12)───────X────────RY(2*p12)────RY(-π/2)───────●────────────────────────────────────X─────────RZ(2*p16)─────RZ(-π/2)────────●────────────────────────────────────X─────────RZ(-π/2)─────PS(p20)───────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p23)───────X────────RY(2*p23)────RY(-π/2)────────●───────────────────────────────────────X─────────RZ(2*p27)─────RZ(-π/2)────────●────────────────────────────────────X───────RZ(-π/2)────PS(p31)──\n", + " │ │ │ │ │ │ │ │ │\n", + "q2: ──X────H────●───────────────X────RZ(2*p2)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────RZ(π/2)────●────RY(π/2)─────RY(-2*p5)────X────RY(2*p5)────RY(-π/2)────●────PS(p10)──────────────────────────────────X─────────RZ(2*p13)─────RZ(-π/2)────────●────────────────────────────────────X───────RZ(-π/2)─────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p16)───────X────────RY(2*p16)────RY(-π/2)───────●─────────PS(p21)────────────────────────────────────X─────────RZ(2*p24)─────RZ(-π/2)────────●─────────────────────────────────────X─────────RZ(-π/2)──────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p27)───────X────────RY(2*p27)────RY(-π/2)───────●───────PS(p32)──────────────\n", + " │ │ │ │ │ │ │ │ │ │\n", + "q3: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p2)────X────RY(2*p2)────RY(-π/2)────●───────────────────────────X────RZ(2*p6)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────PS(p11)──────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p13)───────X────────RY(2*p13)────RY(-π/2)───────●────────────────────────────────────X─────────RZ(2*p17)─────RZ(-π/2)────────●────────────────────────────────────X─────────RZ(-π/2)─────PS(p22)───────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p24)───────X────────RY(2*p24)────RY(-π/2)────────●────────────X─────────RZ(2*p28)─────RZ(-π/2)─────────●──────────────────────────────────────X────────RZ(-π/2)────PS(p33)─────────────────────────\n", + " │ │ │ │ │ │ │ │ │\n", + "q4: ──X────H────●───────────────X────RZ(2*p3)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────RZ(π/2)────●────RY(π/2)─────RY(-2*p6)────X────RY(2*p6)────RY(-π/2)────●────PS(-p11)─────────────────────────────────X─────────RZ(2*p14)─────RZ(-π/2)────────●────────────────────────────────────X───────RZ(-π/2)─────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p17)───────X────────RY(2*p17)────RY(-π/2)───────●─────────PS(-p22)────────X─────────RZ(2*p25)─────RZ(-π/2)─────────●──────────────────────────────────────X────────RZ(-π/2)─────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p28)────────X────────RY(2*p28)─────RY(-π/2)────────●────────PS(-p33)────────────────────────────────────\n", + " │ │ │ │ │ │ │ │ │ │\n", + "q5: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p3)────X────RY(2*p3)────RY(-π/2)────●───────────────────────────X────RZ(2*p7)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────PS(-p10)─────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p14)───────X────────RY(2*p14)────RY(-π/2)───────●──────────X────────RZ(2*p18)─────RZ(-π/2)─────────●──────────────────────────────────────X────────RZ(-π/2)────PS(-p21)─────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p25)────────X────────RY(2*p25)─────RY(-π/2)────────●───────────X────────RZ(2*p29)─────RZ(-π/2)─────────●───────────────────────────────────────X─────────RZ(-π/2)─────PS(-p32)────────────────────────────────────────────────\n", + " │ │ │ │ │ │ │ │ │\n", + "q6: ──X────H────●───────────────X────RZ(2*p4)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────RZ(π/2)────●────RY(π/2)─────RY(-2*p7)────X────RY(2*p7)────RY(-π/2)────●────PS(-p9)────────X────────RZ(2*p15)─────RZ(-π/2)─────────●──────────────────────────────────────X────────RZ(-π/2)────RZ(π/2)───────●─────────RY(π/2)─────RY(-2*p18)────────X────────RY(2*p18)─────RY(-π/2)────────●────────PS(-p20)───────X────────RZ(2*p26)─────RZ(-π/2)─────────●───────────────────────────────────────X─────────RZ(-π/2)─────RZ(π/2)────────●─────────RY(π/2)─────RY(-2*p29)────────X────────RY(2*p29)──────RY(-π/2)────────●─────────PS(-p31)─────────────────────────────────────────────────────────────\n", + " │ │ │ │ │ │ │ │ │ │\n", + "q7: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p4)────X────RY(2*p4)────RY(-π/2)────●────PS(-p8)─────RZ(π/2)───────────────────────────────────────────────────────────────────────────────────●─────────RY(π/2)─────RY(-2*p15)────────X────────RY(2*p15)─────RY(-π/2)────────●────────PS(-p19)────RZ(π/2)──────────────────────────────────────────────────────────────────────────────────────────────────────────────●─────────RY(π/2)─────RY(-2*p26)────────X────────RY(2*p26)──────RY(-π/2)────────●─────────PS(-p30)───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n", + "===========================Circuit Summary===========================\n", + "|Total number of gates : 271. |\n", + "|Parameter gates : 87. |\n", + "|with 33 parameters are : p1, p2, p3, p4, p5, p6, p7, p8, p9, p10...|\n", + "|Number qubit of circuit: 8 |\n", + "=====================================================================\n", + "1 [X0 X1] +\n", + "1 [Y0 Y1] +\n", + "1 [Z0 Z1] +\n", + "1 [X1 X2] +\n", + "1 [Y1 Y2] +\n", + "1 [Z1 Z2] +\n", + "1 [X2 X3] +\n", + "1 [Y2 Y3] +\n", + "1 [Z2 Z3] +\n", + "1 [X3 X4] +\n", + "1 [Y3 Y4] +\n", + "1 [Z3 Z4] +\n", + "1 [X4 X5] +\n", + "1 [Y4 Y5] +\n", + "1 [Z4 Z5] +\n", + "1 [X5 X6] +\n", + "1 [Y5 Y6] +\n", + "1 [Z5 Z6] +\n", + "1 [X6 X7] +\n", + "1 [Y6 Y7] +\n", + "1 [Z6 Z7] \n" + ] + } + ], + "source": [ + "encoder = Circuit()\n", + "for i in range(0, num2, 2):\n", + " encoder += X.on(i)\n", + " encoder += X.on(i + 1)\n", + " encoder += H.on(i)\n", + " encoder += X.on(i + 1, i)\n", + "\n", + "ansatz = Circuit()\n", + "count = 1\n", + "\n", + "for j in range(m2):\n", + " for i in range(0, num2 - 1, 2):\n", + " ansatz += N(count, i)\n", + " count += 1\n", + " for i in range(1, num2 - 1, 2):\n", + " ansatz += N(count, i)\n", + " count += 1\n", + " for i in range(0, num2 // 2):\n", + " ansatz += PhaseShift('p%d' % count).on(i)\n", + " ansatz += PhaseShift({'p%d' % count : -1}).on(num2 - i - 1)\n", + " count += 1\n", + "\n", + "ansatz = encoder + ansatz\n", + "print(ansatz)\n", + "ansatz.summary()\n", + "\n", + "J = 1\n", + "ham = QubitOperator('')\n", + "for i in range(num2 - 1):\n", + " ham += QubitOperator('X%d X%d' % (i, i + 1), J)\n", + " ham += QubitOperator('Y%d Y%d' % (i, i + 1), J)\n", + " ham += QubitOperator('Z%d Z%d' % (i, i + 1), J)\n", + "ham = Hamiltonian(ham - QubitOperator(''))\n", + "\n", + "print(ham)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "调取Strategy 1得到的参数,作为新的线路参数的初猜。论文中指出,如果新的线路的层数大于先前的线路,那么旧参数只应用于原先的层数,多出的层数仍进行随机初始化。此外,对于连接上下两半的一个N门的参数也进行随机初始化。" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5 11\n", + "old parameters:\n", + "p1 0.4028975\n", + "p2 1.7767195\n", + "p3 0.78539985\n", + "p4 -0.44342345\n", + "p5 0.44359204\n", + "p6 -0.23663777\n", + "p7 0.5444191\n", + "p8 -0.54652977\n", + "p9 -1.57108\n", + "p10 -1.5708411\n", + "new parameters:\n", + "p1 0.40289750695228577\n", + "p2 1.7767194509506226\n", + "p3 0.40289750695228577\n", + "p4 1.7767194509506226\n", + "p5 0.785399854183197\n", + "p6 -0.7981621709703667\n", + "p7 0.785399854183197\n", + "p8 -0.44342344999313354\n", + "p9 0.44359204173088074\n", + "p10 -0.44359204173088074\n", + "p11 0.44342344999313354\n", + "p12 -0.23663777112960815\n", + "p13 0.5444191098213196\n", + "p14 -0.23663777112960815\n", + "p15 0.5444191098213196\n", + "p16 -0.5465297698974609\n", + "p17 -0.34117606704058145\n", + "p18 -0.5465297698974609\n", + "p19 -1.571079969406128\n", + "p20 -1.5708410739898682\n", + "p21 1.5708410739898682\n", + "p22 1.571079969406128\n", + "p23 0.17239491160199313\n", + "p24 -0.914783228142229\n", + "p25 -0.590292046100649\n", + "p26 0.5591994325996155\n", + "p27 1.4652410773726405\n", + "p28 -0.40170510817277555\n", + "p29 1.2007430289046384\n", + "p30 -1.0807505299102804\n", + "p31 -0.08635083542922928\n", + "p32 0.6355362236237798\n", + "p33 -0.20765632405686124\n" + ] + } + ], + "source": [ + "pre = pqcnet.weight.asnumpy()\n", + "half = num // 2\n", + "L1 = half * 3 - 1\n", + "L2 = num * 3 - 1\n", + "print(L1, L2)\n", + "val = np.random.randn(L2 * m2)\n", + "for j in range(m):\n", + " for i in range(half):\n", + " val[i + j * L2] = pre[i + j * L1]\n", + " val[i + j * L2 + half] = pre[i + j * L1]\n", + "for j in range(m):\n", + " for i in range(half - 1):\n", + " val[i + j * L2 + num] = pre[i + j * L1 + half]\n", + " val[i + j * L2 + num + half] = pre[i + j * L1 + half]\n", + "for j in range(m):\n", + " for i in range(half):\n", + " val[i + j * L2 + num2 - 1] = pre[i + j * L1 + num - 1]\n", + " val[num - i - 2 + j * L2 + num2] = -pre[i + j * L1 + num - 1]\n", + "\n", + "print('old parameters:')\n", + "for i in range(L1 * m):\n", + " print(f'p{i + 1}', pre[i])\n", + "print('new parameters:')\n", + "for i in range(L2 * m2):\n", + " print(f'p{i + 1}', val[i])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "在新的PQC上使用Adam算法进行梯度优化。" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Initial energy: -0.7443327307701111\n", + "eps: 1e-08\n", + "Step 0 energy -0.7443327307701111\n", + "Step 100 energy -12.1580400466918945\n", + "Step 200 energy -12.3319196701049805\n", + "Step 300 energy -12.5329952239990234\n", + "Step 400 energy -12.8005189895629883\n", + "Step 500 energy -13.1239566802978516\n", + "Step 600 energy -13.2102670669555664\n", + "Step 700 energy -13.2432384490966797\n", + "Step 800 energy -13.2575006484985352\n", + "Step 900 energy -13.2690734863281250\n", + "Step 1000 energy -13.2739782333374023\n", + "Step 1100 energy -13.2763023376464844\n", + "Step 1200 energy -13.2777204513549805\n", + "Step 1300 energy -13.2787160873413086\n", + "Step 1400 energy -13.2794694900512695\n", + "Step 1500 energy -13.2800588607788086\n", + "Step 1600 energy -13.2805252075195312\n", + "Step 1700 energy -13.2808961868286133\n", + "Step 1800 energy -13.2811956405639648\n", + "Step 1900 energy -13.2814435958862305\n", + "Step 2000 energy -13.2816562652587891\n", + "Step 2100 energy -13.2818431854248047\n", + "Step 2200 energy -13.2820081710815430\n", + "Step 2300 energy -13.2821502685546875\n", + "Step 2400 energy -13.2822694778442383\n", + "Optimization completed at step 2492\n", + "Optimized energy: -13.2823591232299805\n", + "Optimized amplitudes: \n", + " [ 0.4028975 1.7767195 0.4028975 1.7767195 0.12742256 -1.1627834\n", + " 0.8583692 1.5402898 1.4963658 1.5271162 1.569726 -1.1491092\n", + " 0.46598285 -0.00386392 0.38710395 0.00827281 0.11402654 -0.52839077\n", + " -1.9126333 -2.0897553 1.5882233 1.5663463 0.06086528 -0.5167987\n", + " -0.05763365 0.01347558 1.5739275 -0.30428478 1.5782783 -2.7471545\n", + " 0.5736982 0.0340413 -0.01536573]\n" + ] + } + ], + "source": [ + "sim = Simulator('projectq', num2)\n", + "pqc = sim.get_expectation_with_grad(ham, ansatz)\n", + "pqcnet = MQAnsatzOnlyLayer(pqc)\n", + "pqcnet.weight = Parameter(ms.Tensor(val, pqcnet.weight.dtype))\n", + "\n", + "initial_energy = pqcnet()\n", + "print(\"Initial energy: %20.16f\" % (initial_energy.asnumpy()))\n", + "\n", + "optimizer = ms.nn.Adam(pqcnet.trainable_params(), learning_rate = 0.01, beta1 = 0.9, beta2 = 0.999, eps = 1e-8)\n", + "train_pqcnet = ms.nn.TrainOneStepCell(pqcnet, optimizer)\n", + "\n", + "eps = 1.e-8\n", + "print(\"eps: \", eps)\n", + "energy_diff = eps * 1000\n", + "energy_last = initial_energy.asnumpy() + energy_diff\n", + "iter_idx = 0\n", + "while (abs(energy_diff) > eps):\n", + " energy_i = train_pqcnet().asnumpy()\n", + " if iter_idx % 100 == 0:\n", + " print(\"Step %3d energy %20.16f\" % (iter_idx, float(energy_i)))\n", + " energy_diff = energy_last - energy_i\n", + " energy_last = energy_i\n", + " iter_idx += 1\n", + "\n", + "print(\"Optimization completed at step %3d\" % (iter_idx - 1))\n", + "print(\"Optimized energy: %20.16f\" % (energy_i))\n", + "print(\"Optimized amplitudes: \\n\", pqcnet.weight.asnumpy())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Strategy 2完整源代码见src/qubit recursive.py,相较本文档,源代码从目标的$N$出发,尽可能从$N$中除掉2的幂,再往上倍增至$N$。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "值得一提的是,论文中并没有明确给出子系统的收敛的判据。论文前文在随机初始化的段落给出“对约100个不同的随机初始化参数,只有它们全部都能在50L次循环后达到保真度阈值,才判定算法成功”,这个判据显然不能应用在这个场景里,因为实际VQE的过程中目标态是未知的,无法计算保真度,只能比较更新步骤之间的能量差。从极端情形考虑,如果收敛判据取得非常严苛(阈值取得非常小),那么大量的循环都浪费在子系统PQC的收敛上,反而达不到加速的效果。\n", + "\n", + "由此考虑,可以将子系统收敛的阈值取得稍大一些,因为通过改善子系统的基态的精度来提高目标系统的精度,这件事情的效率是相对较低的。绝大部分的经典迭代应该用在最终的目标系统上。由于参数的不确定性,无法从理论上给出这一“效率”的大小,从经验上不妨试着取子系统阈值为后一步2倍大系统的10或100倍。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 改进Strategy 2\n", + "\n", + "论文中指出,使用Strategy 2的动机是:单独考虑子系统的基态(the ground state of the local system),与大系统的基态的子系统空间(the reduced density matrix of the subsystems from the ground state of the large system)很相似。从物理的角度分析,这个说法肯定是合理的,因为哈密顿量可以改写为$H_N=J (\\sum_{i=1}^{N/2-1} \\sigma^{i} \\cdot \\sigma^{i+1}+\\sum_{i=N/2}^{N-1} \\sigma^{i} \\cdot \\sigma^{i+1}+\\sigma^{N/2-1} \\cdot \\sigma^{N/2})$.这个式子的前两项分别对应两个子系统,把它们的和看作一个整体$H_{base}$,它的基态就是两个$H_{N/2}$的基态的张量积$|\\Psi_{base}\\rangle=|\\Psi_{N/2}\\rangle \\otimes |\\Psi_{N/2}\\rangle$,而真正的哈密顿量$H_N$可以看作是$H_{base}$上的微扰$H_N=H_{base}+\\sigma^{N/2-1} \\cdot \\sigma^{N/2}$,根据微扰论的知识,$N$越大,$|\\Psi_{base}\\rangle$与$|\\Psi_{N}\\rangle$的差距就越小。\n", + "\n", + "既然如此,为什么不从物理上认可的$H_{base}$出发作变分呢?想要制备$H_{base}$,就应该让连接上下两半的N门的参数取0,如果新增加了线路层数,那么所有的新添加的参数门的参数也应都取0.论文中将的连接的门和新添加的门的参数随机初始化,是否反而是在南辕北辙?可以做一个简单的验证:从前文中获取的子网络参数pre重新构建线路,Attempt1将连接的门的参数设置为0,Attempt2将连接的门和新添加的门的参数全都设置为0,比较这两者的能量与之前的线路的能量的高低。" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Attempt 1 better: 57.4%\n", + "Attempt 2 better: 74.5%\n" + ] + } + ], + "source": [ + "pre = pqcnet.weight.asnumpy()\n", + "half = num // 2\n", + "L1 = half * 3 - 1\n", + "L2 = num * 3 - 1\n", + "\n", + "count1 = 0\n", + "count2 = 0\n", + "numoftests = 1000\n", + "for k in range(numoftests):\n", + " val = np.random.randn(L2 * m2)\n", + "\n", + " for j in range(m):\n", + " for i in range(half):\n", + " val[i + j * L2] = pre[i + j * L1]\n", + " val[i + j * L2 + half] = pre[i + j * L1]\n", + " for j in range(m):\n", + " for i in range(half - 1):\n", + " val[i + j * L2 + num] = pre[i + j * L1 + half]\n", + " val[i + j * L2 + num + half] = pre[i + j * L1 + half]\n", + " for j in range(m):\n", + " for i in range(half):\n", + " val[i + j * L2 + num2 - 1] = pre[i + j * L1 + num - 1]\n", + " val[num - i - 2 + j * L2 + num2] = -pre[i + j * L1 + num - 1]\n", + "\n", + " sim = Simulator('projectq', num2)\n", + " pqc = sim.get_expectation_with_grad(ham, ansatz)\n", + " pqcnet = MQAnsatzOnlyLayer(pqc)\n", + " pqcnet.weight = Parameter(ms.Tensor(val, pqcnet.weight.dtype))\n", + "\n", + " initial_energy1 = pqcnet()\n", + " #print(\"Paper Initial energy: %20.16f\" % (initial_energy.asnumpy()))\n", + "\n", + " for j in range(m):\n", + " val[j * L2 + num + half - 1] = 0\n", + " pqcnet.weight = Parameter(ms.Tensor(val, pqcnet.weight.dtype))\n", + " initial_energy2 = pqcnet()\n", + " #print(\"Attempt 1 Initial energy: %20.16f\" % (initial_energy.asnumpy()))\n", + "\n", + " val = np.zeros(L2 * m2)\n", + " for j in range(m):\n", + " for i in range(half):\n", + " val[i + j * L2] = pre[i + j * L1]\n", + " val[i + j * L2 + half] = pre[i + j * L1]\n", + " for j in range(m):\n", + " for i in range(half - 1):\n", + " val[i + j * L2 + num] = pre[i + j * L1 + half]\n", + " val[i + j * L2 + num + half] = pre[i + j * L1 + half]\n", + " for j in range(m):\n", + " for i in range(half):\n", + " val[i + j * L2 + num2 - 1] = pre[i + j * L1 + num - 1]\n", + " val[num - i - 2 + j * L2 + num2] = -pre[i + j * L1 + num - 1]\n", + " pqcnet.weight = Parameter(ms.Tensor(val, pqcnet.weight.dtype))\n", + " initial_energy3 = pqcnet()\n", + " #print(\"Attempt 2 Initial energy: %20.16f\" % (initial_energy.asnumpy()))\n", + " if initial_energy2 < initial_energy1:\n", + " count1 +=1\n", + " if initial_energy3 < initial_energy1:\n", + " count2 +=1\n", + "print('Attempt 1 better: %.1f' % (100.0*count1/numoftests) + '%')\n", + "print('Attempt 2 better: %.1f' % (100.0*count2/numoftests) + '%')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "可以看到大多数情况下,随机初始化将量子态偏离$|\\Psi_{base}\\rangle$,其得到的结果反而不如$|\\Psi_{base}\\rangle$,因此不如就将$|\\Psi_{base}\\rangle$作为大系统变分的起点。整体线路的随机性由最小的子系统的参数的随机初始化实现。\n", + "\n", + "在src/qubit recursive.py中,解除第165、166行的注释即可实现Attempt1,解除第167行的注释即可实现Attempt2." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Strategy 3: layer recursive.\n", + "\n", + "这个策略先从单层的PQC出发,达到收敛之后,增加一层PQC的层数(使用前一层的参数作为初猜),达到收敛之后再增加一层,以此类推直至总层数达到$M_{VQE}$.\n", + "\n", + "论文中没有给出使用这一策略的理论依据。个人认为这一策略的可以从几何上理解,在经过VQE的变分优化后,如果恰好初态、末态和目标态三者共面,那么下一步的参数的最优取值一定是前一步的复制,不共面时也是不错的贪心策略。这与Grover算法的思路类似。" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Current number of layers: 1\n", + "Initial energy: 0.0123526062816381\n", + "eps: 1e-08\n", + "Step 0 energy 0.0123526062816381\n", + "Optimization completed at step 94\n", + "Optimized energy: 0.0000000000238039\n", + "Optimized amplitudes: \n", + " [-1.8926561 0.168481 -0.78533477 -0.46012077 -1.4066193 ]\n", + "Current number of layers: 2\n", + "Initial energy: -2.3261110782623291\n", + "eps: 1e-08\n", + "Step 0 energy -2.3261110782623291\n", + "Step 100 energy -5.9998421669006348\n", + "Optimization completed at step 124\n", + "Optimized energy: -5.9999876022338867\n", + "Optimized amplitudes: \n", + " [-1.8926561 0.168481 -0.78522205 -0.32984713 -0.8735825 -1.8141392\n", + " 0.24335901 -0.78527933 -0.32926998 -1.5350333 ]\n" + ] + } + ], + "source": [ + "num = 4\n", + "m = NMtable[num]\n", + "assert num % 2 == 0\n", + "#print(num, m)\n", + "\n", + "\n", + "encoder = Circuit()\n", + "for i in range(0, num, 2):\n", + " encoder += X.on(i)\n", + " encoder += X.on(i + 1)\n", + " encoder += H.on(i)\n", + " encoder += X.on(i + 1, i)\n", + " \n", + "#print(encoder)\n", + "#encoder.summary()\n", + "\n", + "\n", + "J = 1\n", + "ham = QubitOperator('')\n", + "for i in range(num - 1):\n", + " ham += QubitOperator('X%d X%d' % (i, i + 1), J)\n", + " ham += QubitOperator('Y%d Y%d' % (i, i + 1), J)\n", + " ham += QubitOperator('Z%d Z%d' % (i, i + 1), J)\n", + "ham -= QubitOperator('')\n", + "\n", + "#print(ham)\n", + "\n", + "\n", + "ansatz = encoder\n", + "count = 1\n", + "sim = Simulator('projectq', num)\n", + "val = []\n", + "L = num // 2 * 3 - 1\n", + "\n", + "for j in range(m):\n", + " print(f'Current number of layers: {j + 1}')\n", + " # print(val)\n", + " for i in range(0, num - 1, 2):\n", + " ansatz += N(count, i)\n", + " count += 1\n", + " for i in range(1, num - 1, 2):\n", + " ansatz += N(count, i)\n", + " count += 1\n", + " for i in range(0, num // 2):\n", + " ansatz += PhaseShift('p%d' % count).on(i)\n", + " ansatz += PhaseShift({'p%d' % count : -1}).on(num - i - 1)\n", + " count += 1\n", + "\n", + " # print(ansatz)\n", + " # ansatz.summary()\n", + "\n", + " if j == 0:\n", + " val = np.random.randn(count - 1)\n", + " else:\n", + " val = np.concatenate((val, val[-L:]))\n", + " # print(val)\n", + "\n", + " \n", + " pqc = sim.get_expectation_with_grad(Hamiltonian(ham), ansatz)\n", + " pqcnet = MQAnsatzOnlyLayer(pqc)\n", + " pqcnet.weight = Parameter(ms.Tensor(val, pqcnet.weight.dtype))\n", + "\n", + " initial_energy = pqcnet()\n", + " print(\"Initial energy: %20.16f\" % (initial_energy.asnumpy()))\n", + "\n", + "\n", + " optimizer = ms.nn.Adam(pqcnet.trainable_params(), learning_rate = 0.01, beta1 = 0.9, beta2 = 0.999, eps = 1e-8)\n", + " train_pqcnet = ms.nn.TrainOneStepCell(pqcnet, optimizer)\n", + "\n", + " eps = 1.e-8\n", + " print(\"eps: \", eps)\n", + " energy_diff = eps * 1000\n", + " energy_last = initial_energy.asnumpy() + energy_diff\n", + " iter_idx = 0\n", + " while (abs(energy_diff) > eps):\n", + " energy_i = train_pqcnet().asnumpy()\n", + " if iter_idx % 100 == 0:\n", + " print(\"Step %3d energy %20.16f\" % (iter_idx, float(energy_i)))\n", + " energy_diff = energy_last - energy_i\n", + " energy_last = energy_i\n", + " iter_idx += 1\n", + "\n", + " print(\"Optimization completed at step %3d\" % (iter_idx - 1))\n", + " print(\"Optimized energy: %20.16f\" % (energy_i))\n", + " print(\"Optimized amplitudes: \\n\", pqcnet.weight.asnumpy())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Strategy 3完整源代码见src/layer recursive.py" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 项目总结" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 复现结果\n", + "实现了论文Sec.5中的3种不同策略的VQE线路,3种都可以复现N=4、8、10时海森堡模型的基态能量。\n", + "### 创新点\n", + "改进了Strategy 2中的参数初猜设定\n", + "### 未来可继续研究的方向\n", + "1. 论文绘制了许多与保真度相关的图表,由于mindquantum没有内置的矩阵严格对角化的功能,这些图表若要在mindquantum中重现,需要从外部导入严格对角化的结果,与ansatz.get_qs(pr = val)的结果作内积,这里由于位序的定义问题很容易引发错误。可以考虑内置矩阵严格对角化。\n", + "2. 由于密度矩阵模块尚不健全,无法模拟双量子比特门的失相,可以考虑引入密度矩阵,Kraus算符等模块。\n", + "3. 文中固定了使用Adam算法,取了一组特定的学习率等参数,可以探索不同的经典优化算法,不同参数之间的性能差异。\n", + "4. 可以探索绝热演化转VQE这一线路设计范式在其他模型中的应用。" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "MindQuantum", + "language": "python", + "name": "mindquantum" + }, + "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": 4 +} diff --git a/paper_recurrence/6_hw08624896/readme.md b/paper_recurrence/6_hw08624896/readme.md new file mode 100644 index 000000000..75f334ec7 --- /dev/null +++ b/paper_recurrence/6_hw08624896/readme.md @@ -0,0 +1,15 @@ +# Accelerated variational algorithms for digital quantum simulation of the many-body ground states + +## 项目介绍 + +用VQE制备一维海森堡模型的基态,线路设计由绝热演化的Suzuki-Trotter expansion启发而来,并着重探讨了优化经典参数更新循环的3种策略。 + +## 主要结果 + +实现了论文Sec.5中的3种不同策略的VQE线路,3种都可以复现N=4、8、10时海森堡模型的基态能量。 + +## 创新点 + +改进了Strategy 2中的参数初猜设定。 + +邮箱地址:jerryhts@163.com \ No newline at end of file diff --git a/paper_recurrence/6_hw08624896/src/accvqeexact.py b/paper_recurrence/6_hw08624896/src/accvqeexact.py new file mode 100644 index 000000000..74c1a318a --- /dev/null +++ b/paper_recurrence/6_hw08624896/src/accvqeexact.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Jan 17 13:00:24 2022 + +@author: Jerryhts +""" + +import numpy as np + +X = np.array([[0, 1], [1, 0]]) +Y = np.array([[0, -1j], [1j, 0]]) +Z = np.array([[1, 0], [0, -1]]) +I = np.array([[1, 0], [0, 1]]) +''' +def RX(t): + return np.array([[np.cos(t / 2), -1j * np.sin(t / 2)], [-1j * np.sin(t / 2), np.cos(t / 2)]]) +def RY(t): + return np.array([[np.cos(t / 2), -np.sin(t / 2)], [np.sin(t / 2), np.cos(t / 2)]]) +def RZ(t): + return np.array([[np.exp(-1j * t / 2), 0], [0, np.exp(1j * t / 2)]])''' + +def f(x): + if x == 'X': + return X + elif x == 'Y': + return Y + elif x == 'Z': + return Z + else: + return I + +tot = 2 +num = 2 + +def QubitOperator(string, para): + al = ['I' for i in range(tot)] + tem = string.split(' ') + for i in tem: + num = eval(i[1:]) + al[num] = i[0] + ini = f(al[0]) + for i in range(1, tot): + ini = np.kron(f(al[i]), ini) + return para * ini + +J = 1 +ham = np.complex128(np.zeros((2 ** tot, 2 ** tot))) +for i in range(num - 1): + ham += QubitOperator('X%d X%d' % (i, i + 1), J) + ham += QubitOperator('Y%d Y%d' % (i, i + 1), J) + ham += QubitOperator('Z%d Z%d' % (i, i + 1), J) + +w, v = np.linalg.eig(ham) +res = np.sort(np.real(w)) +print(res) \ No newline at end of file diff --git a/paper_recurrence/6_hw08624896/src/layer recursive.py b/paper_recurrence/6_hw08624896/src/layer recursive.py new file mode 100644 index 000000000..4e27d221e --- /dev/null +++ b/paper_recurrence/6_hw08624896/src/layer recursive.py @@ -0,0 +1,111 @@ +import numpy as np +from mindquantum import Circuit, X, H, RZ, RY, PhaseShift, Hamiltonian, Simulator, QubitOperator, Hamiltonian, MQAnsatzOnlyLayer +import mindspore as ms +from mindspore.common.parameter import Parameter +import mindspore.context as context + +context.set_context(mode=context.PYNATIVE_MODE, device_target="CPU") + + +def N(count, i): + temp = Circuit() + temp += RZ(np.pi / 2).on(i + 1) + temp += X.on(i, i + 1) + temp += RZ({f'p{count}' : 2}).on(i) + temp += RZ(-np.pi / 2).on(i) + temp += RY(np.pi / 2).on(i + 1) + temp += RY({f'p{count}' : -2}).on(i + 1) + temp += X.on(i + 1, i) + temp += RY({f'p{count}' : 2}).on(i + 1) + temp += RY(-np.pi / 2).on(i + 1) + temp += X.on(i, i + 1) + temp += RZ(-np.pi / 2).on(i) + return temp + + +NMtable = {4:2, 8:3, 10:3, 16:5, 20:6} +num = 4 +m = NMtable[num] +assert num % 2 == 0 +#print(num, m) + + +encoder = Circuit() +for i in range(0, num, 2): + encoder += X.on(i) + encoder += X.on(i + 1) + encoder += H.on(i) + encoder += X.on(i + 1, i) + +#print(encoder) +#encoder.summary() + + +J = 1 +ham = QubitOperator('') +for i in range(num - 1): + ham += QubitOperator('X%d X%d' % (i, i + 1), J) + ham += QubitOperator('Y%d Y%d' % (i, i + 1), J) + ham += QubitOperator('Z%d Z%d' % (i, i + 1), J) +ham -= QubitOperator('') + +#print(ham) + + +ansatz = encoder +count = 1 +sim = Simulator('projectq', num) +val = [] +L = num // 2 * 3 - 1 + +for j in range(m): + print(f'Current number of layers: {j + 1}') + # print(val) + for i in range(0, num - 1, 2): + ansatz += N(count, i) + count += 1 + for i in range(1, num - 1, 2): + ansatz += N(count, i) + count += 1 + for i in range(0, num // 2): + ansatz += PhaseShift('p%d' % count).on(i) + ansatz += PhaseShift({'p%d' % count : -1}).on(num - i - 1) + count += 1 + + # print(ansatz) + # ansatz.summary() + + if j == 0: + val = np.random.randn(count - 1) + else: + val = np.concatenate((val, val[-L:])) + # print(val) + + + pqc = sim.get_expectation_with_grad(Hamiltonian(ham), ansatz) + pqcnet = MQAnsatzOnlyLayer(pqc) + pqcnet.weight = Parameter(ms.Tensor(val, pqcnet.weight.dtype)) + + initial_energy = pqcnet() + print("Initial energy: %20.16f" % (initial_energy.asnumpy())) + + + optimizer = ms.nn.Adam(pqcnet.trainable_params(), learning_rate = 0.01, beta1 = 0.9, beta2 = 0.999, eps = 1e-8) + train_pqcnet = ms.nn.TrainOneStepCell(pqcnet, optimizer) + + eps = 1.e-8 + print("eps: ", eps) + energy_diff = eps * 1000 + energy_last = initial_energy.asnumpy() + energy_diff + iter_idx = 0 + while (abs(energy_diff) > eps): + energy_i = train_pqcnet().asnumpy() + if iter_idx % 100 == 0: + print("Step %3d energy %20.16f" % (iter_idx, float(energy_i))) + energy_diff = energy_last - energy_i + energy_last = energy_i + iter_idx += 1 + + print("Optimization completed at step %3d" % (iter_idx - 1)) + print("Optimized energy: %20.16f" % (energy_i)) + print("Optimized amplitudes: \n", pqcnet.weight.asnumpy()) \ No newline at end of file diff --git a/paper_recurrence/6_hw08624896/src/qubit recursive.py b/paper_recurrence/6_hw08624896/src/qubit recursive.py new file mode 100644 index 000000000..7066348b5 --- /dev/null +++ b/paper_recurrence/6_hw08624896/src/qubit recursive.py @@ -0,0 +1,219 @@ +import numpy as np +from mindquantum import Circuit, X, H, RZ, RY, PhaseShift, Hamiltonian, Simulator, QubitOperator, Hamiltonian, MQAnsatzOnlyLayer +import mindspore as ms +from mindspore.common.parameter import Parameter +import mindspore.context as context + +context.set_context(mode=context.PYNATIVE_MODE, device_target="CPU") + + +def N(count, i): + temp = Circuit() + temp += RZ(np.pi / 2).on(i + 1) + temp += X.on(i, i + 1) + temp += RZ({f'p{count}' : 2}).on(i) + temp += RZ(-np.pi / 2).on(i) + temp += RY(np.pi / 2).on(i + 1) + temp += RY({f'p{count}' : -2}).on(i + 1) + temp += X.on(i + 1, i) + temp += RY({f'p{count}' : 2}).on(i + 1) + temp += RY(-np.pi / 2).on(i + 1) + temp += X.on(i, i + 1) + temp += RZ(-np.pi / 2).on(i) + return temp + + +NMtable = {4:2, 8:3, 10:3, 16:5, 20:6} +num = 8 + + +temp = num +while num % 2 == 0 and num > 4: + num = num // 2 +m = NMtable[num] +assert num % 2 == 0 + +print(f'Current N: {num}') + + +encoder = Circuit() +for i in range(0, num, 2): + encoder += X.on(i) + encoder += X.on(i + 1) + encoder += H.on(i) + encoder += X.on(i + 1, i) + +# print(encoder) +# encoder.summary() + + +ansatz = Circuit() +count = 1 + +for j in range(m): + for i in range(0, num - 1, 2): + ansatz += N(count, i) + count += 1 + for i in range(1, num - 1, 2): + ansatz += N(count, i) + count += 1 + for i in range(0, num // 2): + ansatz += PhaseShift('p%d' % count).on(i) + ansatz += PhaseShift({'p%d' % count : -1}).on(num - i - 1) + count += 1 + +ansatz = encoder + ansatz + +# print(ansatz) +# ansatz.summary() + + +J = 1 +ham = QubitOperator('') +for i in range(num - 1): + ham += QubitOperator('X%d X%d' % (i, i + 1), J) + ham += QubitOperator('Y%d Y%d' % (i, i + 1), J) + ham += QubitOperator('Z%d Z%d' % (i, i + 1), J) +ham -= QubitOperator('') + +# print(ham) + + +val = np.random.randn(count - 1) + +sim = Simulator('projectq', num) +pqc = sim.get_expectation_with_grad(Hamiltonian(ham), ansatz) +pqcnet = MQAnsatzOnlyLayer(pqc) +pqcnet.weight = Parameter(ms.Tensor(val, pqcnet.weight.dtype)) + +initial_energy = pqcnet() +print("Initial energy: %20.16f" % (initial_energy.asnumpy())) + + +optimizer = ms.nn.Adam(pqcnet.trainable_params(), learning_rate = 0.01, beta1 = 0.9, beta2 = 0.999, eps = 1e-8) +train_pqcnet = ms.nn.TrainOneStepCell(pqcnet, optimizer) + +eps = 1.e-8 +print("eps: ", eps) +energy_diff = eps * 1000 +energy_last = initial_energy.asnumpy() + energy_diff +iter_idx = 0 +while (abs(energy_diff) > eps): + energy_i = train_pqcnet().asnumpy() + if iter_idx % 100 == 0: + print("Step %3d energy %20.16f" % (iter_idx, float(energy_i))) + energy_diff = energy_last - energy_i + energy_last = energy_i + iter_idx += 1 + +print("Optimization completed at step %3d" % (iter_idx - 1)) +print("Optimized energy: %20.16f" % (energy_i)) +print("Optimized amplitudes: \n", pqcnet.weight.asnumpy()) + + +while num < temp: + num2 = 2 * num + m2 = NMtable[num2] + # print(num2, m2) + + print(f'Current N: {num2}') + + + encoder = Circuit() + for i in range(0, num2, 2): + encoder += X.on(i) + encoder += X.on(i + 1) + encoder += H.on(i) + encoder += X.on(i + 1, i) + + ansatz = Circuit() + count = 1 + + for j in range(m2): + for i in range(0, num2 - 1, 2): + ansatz += N(count, i) + count += 1 + for i in range(1, num2 - 1, 2): + ansatz += N(count, i) + count += 1 + for i in range(0, num2 // 2): + ansatz += PhaseShift('p%d' % count).on(i) + ansatz += PhaseShift({'p%d' % count : -1}).on(num2 - i - 1) + count += 1 + + ansatz = encoder + ansatz + # print(ansatz) + # ansatz.summary() + + J = 1 + ham = QubitOperator('') + for i in range(num2 - 1): + ham += QubitOperator('X%d X%d' % (i, i + 1), J) + ham += QubitOperator('Y%d Y%d' % (i, i + 1), J) + ham += QubitOperator('Z%d Z%d' % (i, i + 1), J) + ham = Hamiltonian(ham - QubitOperator('')) + + # print(ham) + + + pre = pqcnet.weight.asnumpy() + half = num // 2 + L1 = half * 3 - 1 + L2 = num * 3 - 1 + # print(L1, L2) + val = np.random.randn(L2 * m2) + # for j in range(m): + # val[j * L2 + num + half - 1] = 0 # To utilize Attempt 1 + # val = np.zeros(L2 * m2) # To utilize Attempt 2 + + for j in range(m): + for i in range(half): + val[i + j * L2] = pre[i + j * L1] + val[i + j * L2 + half] = pre[i + j * L1] + for j in range(m): + for i in range(half - 1): + val[i + j * L2 + num] = pre[i + j * L1 + half] + val[i + j * L2 + num + half] = pre[i + j * L1 + half] + for j in range(m): + for i in range(half): + val[i + j * L2 + num2 - 1] = pre[i + j * L1 + num - 1] + val[num - i - 2 + j * L2 + num2] = -pre[i + j * L1 + num - 1] + + '''print('old parameters:') + for i in range(L1 * m): + print(f'p{i + 1}', pre[i]) + print('new parameters:') + for i in range(L2 * m2): + print(f'p{i + 1}', val[i])''' + + + sim = Simulator('projectq', num2) + pqc = sim.get_expectation_with_grad(ham, ansatz) + pqcnet = MQAnsatzOnlyLayer(pqc) + pqcnet.weight = Parameter(ms.Tensor(val, pqcnet.weight.dtype)) + + initial_energy = pqcnet() + print("Initial energy: %20.16f" % (initial_energy.asnumpy())) + + optimizer = ms.nn.Adam(pqcnet.trainable_params(), learning_rate = 0.01, beta1 = 0.9, beta2 = 0.999, eps = 1e-8) + train_pqcnet = ms.nn.TrainOneStepCell(pqcnet, optimizer) + + eps = 1.e-8 + print("eps: ", eps) + energy_diff = eps * 1000 + energy_last = initial_energy.asnumpy() + energy_diff + iter_idx = 0 + while (abs(energy_diff) > eps): + energy_i = train_pqcnet().asnumpy() + if iter_idx % 100 == 0: + print("Step %3d energy %20.16f" % (iter_idx, float(energy_i))) + energy_diff = energy_last - energy_i + energy_last = energy_i + iter_idx += 1 + + print("Optimization completed at step %3d" % (iter_idx - 1)) + print("Optimized energy: %20.16f" % (energy_i)) + print("Optimized amplitudes: \n", pqcnet.weight.asnumpy()) + + num = num2 + m = m2 \ No newline at end of file diff --git a/paper_recurrence/6_hw08624896/src/random initialization.py b/paper_recurrence/6_hw08624896/src/random initialization.py new file mode 100644 index 000000000..9e6eecd65 --- /dev/null +++ b/paper_recurrence/6_hw08624896/src/random initialization.py @@ -0,0 +1,105 @@ +import numpy as np +from mindquantum import Circuit, X, H, RZ, RY, PhaseShift, Hamiltonian, Simulator, QubitOperator, Hamiltonian, MQAnsatzOnlyLayer +import mindspore as ms +from mindspore.common.parameter import Parameter +import mindspore.context as context + +context.set_context(mode=context.PYNATIVE_MODE, device_target="CPU") + + +def N(count, i): + temp = Circuit() + temp += RZ(np.pi / 2).on(i + 1) + temp += X.on(i, i + 1) + temp += RZ({f'p{count}' : 2}).on(i) + temp += RZ(-np.pi / 2).on(i) + temp += RY(np.pi / 2).on(i + 1) + temp += RY({f'p{count}' : -2}).on(i + 1) + temp += X.on(i + 1, i) + temp += RY({f'p{count}' : 2}).on(i + 1) + temp += RY(-np.pi / 2).on(i + 1) + temp += X.on(i, i + 1) + temp += RZ(-np.pi / 2).on(i) + return temp + + +NMtable = {4:2, 8:3, 10:3, 16:5, 20:6} +num = 4 +m = NMtable[num] +assert num % 2 == 0 +# print(num, m) + + +encoder = Circuit() +for i in range(0, num, 2): + encoder += X.on(i) + encoder += X.on(i + 1) + encoder += H.on(i) + encoder += X.on(i + 1, i) + +# print(encoder) +# encoder.summary() + + +ansatz = Circuit() +count = 1 + +for j in range(m): + for i in range(0, num - 1, 2): + ansatz += N(count, i) + count += 1 + for i in range(1, num - 1, 2): + ansatz += N(count, i) + count += 1 + for i in range(0, num // 2): + ansatz += PhaseShift('p%d' % count).on(i) + ansatz += PhaseShift({'p%d' % count : -1}).on(num - i - 1) + count += 1 + +ansatz = encoder + ansatz + +# print(ansatz) +# ansatz.summary() + + +J = 1 +ham = QubitOperator('') +for i in range(num - 1): + ham += QubitOperator('X%d X%d' % (i, i + 1), J) + ham += QubitOperator('Y%d Y%d' % (i, i + 1), J) + ham += QubitOperator('Z%d Z%d' % (i, i + 1), J) +ham -= QubitOperator('') + +# print(ham) + + +val = np.random.randn(count - 1) + +sim = Simulator('projectq', num) +pqc = sim.get_expectation_with_grad(Hamiltonian(ham), ansatz) +pqcnet = MQAnsatzOnlyLayer(pqc) +pqcnet.weight = Parameter(ms.Tensor(val, pqcnet.weight.dtype)) + +initial_energy = pqcnet() +print("Initial energy: %20.16f" % (initial_energy.asnumpy())) + + +optimizer = ms.nn.Adam(pqcnet.trainable_params(), learning_rate = 0.01, beta1 = 0.9, beta2 = 0.999, eps = 1e-8) +train_pqcnet = ms.nn.TrainOneStepCell(pqcnet, optimizer) + +eps = 1.e-8 +print("eps: ", eps) +energy_diff = eps * 1000 +energy_last = initial_energy.asnumpy() + energy_diff +iter_idx = 0 +while (abs(energy_diff) > eps): + energy_i = train_pqcnet().asnumpy() + if iter_idx % 100 == 0: + print("Step %3d energy %20.16f" % (iter_idx, float(energy_i))) + energy_diff = energy_last - energy_i + energy_last = energy_i + iter_idx += 1 + +print("Optimization completed at step %3d" % (iter_idx - 1)) +print("Optimized energy: %20.16f" % (energy_i)) +print("Optimized amplitudes: \n", pqcnet.weight.asnumpy()) \ No newline at end of file diff --git a/paper_recurrence/6_hw08624896/src/readme.md b/paper_recurrence/6_hw08624896/src/readme.md new file mode 100644 index 000000000..5300eb462 --- /dev/null +++ b/paper_recurrence/6_hw08624896/src/readme.md @@ -0,0 +1 @@ +# 请将你对论文复现的源代码放置于当下src文件夹内。 \ No newline at end of file -- Gitee From 28a59f0e14f227069e1d287da485509102ba46c2 Mon Sep 17 00:00:00 2001 From: he-tianshen Date: Mon, 14 Feb 2022 10:41:26 +0800 Subject: [PATCH 2/2] 6_hw08624896 --- paper_recurrence/6_hw08624896/main.ipynb | 175 +++++++++++++++++------ 1 file changed, 135 insertions(+), 40 deletions(-) diff --git a/paper_recurrence/6_hw08624896/main.ipynb b/paper_recurrence/6_hw08624896/main.ipynb index 45d8c6c0f..6423505d2 100644 --- a/paper_recurrence/6_hw08624896/main.ipynb +++ b/paper_recurrence/6_hw08624896/main.ipynb @@ -156,20 +156,13 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "q0: ──X────H────●──\n", - " │\n", - "q1: ──X─────────X──\n", - "\n", - "q2: ──X────H────●──\n", - " │\n", - "q3: ──X─────────X──\n", "=======Circuit Summary=======\n", "|Total number of gates : 8.|\n", "|Parameter gates : 0.|\n", @@ -177,6 +170,42 @@ "|Number qubit of circuit: 4 |\n", "=============================\n" ] + }, + { + "data": { + "text/html": [ + "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "
q0: ──X────H────●──\n",
+       "\n",
+       "q1: ──X─────────X──\n",
+       "\n",
+       "q2: ──X────H────●──\n",
+       "\n",
+       "q3: ──X─────────X──\n",
+       "
\n" + ], + "text/plain": [ + "q0: ──X────H────●──\n", + " │\n", + "q1: ──X─────────X──\n", + "\n", + "q2: ──X────H────●──\n", + " │\n", + "q3: ──X─────────X──" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ @@ -187,8 +216,8 @@ " encoder += H.on(i)\n", " encoder += X.on(i + 1, i)\n", " \n", - "print(encoder)\n", - "encoder.summary()" + "encoder.summary()\n", + "encoder" ] }, { @@ -200,20 +229,13 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "q0: ──X────H────●───────────────X────RZ(2*p1)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)─────PS(p4)──────────────────────────────────────────────────────────────────────────────────────────────────────────X────────RZ(2*p6)─────RZ(-π/2)───────●───────────────────────────────────X───────RZ(-π/2)─────PS(p9)─────────────────────────────────────────────────────────────────────────\n", - " │ │ │ │ │ │ │\n", - "q1: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p1)────X────RY(2*p1)────RY(-π/2)────●───────────────────────────X────RZ(2*p3)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────PS(p5)────RZ(π/2)─────────●────────RY(π/2)─────RY(-2*p6)───────X────────RY(2*p6)────RY(-π/2)───────●──────────X────────RZ(2*p8)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────PS(p10)──\n", - " │ │ │ │ │ │\n", - "q2: ──X────H────●───────────────X────RZ(2*p2)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────RZ(π/2)────●────RY(π/2)─────RY(-2*p3)────X────RY(2*p3)────RY(-π/2)────●────PS(-p5)───────X───────RZ(2*p7)─────RZ(-π/2)───────●────────────────────────────────────X────────RZ(-π/2)────RZ(π/2)───────●────────RY(π/2)─────RY(-2*p8)────X────RY(2*p8)────RY(-π/2)────●────PS(-p10)─────────────\n", - " │ │ │ │ │ │ │\n", - "q3: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p2)────X────RY(2*p2)────RY(-π/2)────●────PS(-p4)─────RZ(π/2)──────────────────────────────────────────────────────────────────────────────────●───────RY(π/2)─────RY(-2*p7)───────X─────────RY(2*p7)────RY(-π/2)───────●────────PS(-p9)────────────────────────────────────────────────────────────────────────────────────────────────────────────\n", "==========================Circuit Summary==========================\n", "|Total number of gates : 82. |\n", "|Parameter gates : 26. |\n", @@ -221,6 +243,42 @@ "|Number qubit of circuit: 4 |\n", "===================================================================\n" ] + }, + { + "data": { + "text/html": [ + "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "
q0: ──X────H────●───────────────X────RZ(2*p1)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)─────PS(p4)──────────────────────────────────────────────────────────────────────────────────────────────────────────X────────RZ(2*p6)─────RZ(-π/2)───────●───────────────────────────────────X───────RZ(-π/2)─────PS(p9)─────────────────────────────────────────────────────────────────────────\n",
+       "                │               │                             │                            │                                                                                                                                 │                                    │                                   │\n",
+       "q1: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p1)────X────RY(2*p1)────RY(-π/2)────●───────────────────────────X────RZ(2*p3)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────PS(p5)────RZ(π/2)─────────●────────RY(π/2)─────RY(-2*p6)───────X────────RY(2*p6)────RY(-π/2)───────●──────────X────────RZ(2*p8)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────PS(p10)──\n",
+       "                                                                                                                       │                             │                            │                                                                                                                              │                                 │                            │\n",
+       "q2: ──X────H────●───────────────X────RZ(2*p2)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────RZ(π/2)────●────RY(π/2)─────RY(-2*p3)────X────RY(2*p3)────RY(-π/2)────●────PS(-p5)───────X───────RZ(2*p7)─────RZ(-π/2)───────●────────────────────────────────────X────────RZ(-π/2)────RZ(π/2)───────●────────RY(π/2)─────RY(-2*p8)────X────RY(2*p8)────RY(-π/2)────●────PS(-p10)─────────────\n",
+       "                │               │                             │                            │                                                                                                         │                                   │                                    │\n",
+       "q3: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p2)────X────RY(2*p2)────RY(-π/2)────●────PS(-p4)─────RZ(π/2)──────────────────────────────────────────────────────────────────────────────────●───────RY(π/2)─────RY(-2*p7)───────X─────────RY(2*p7)────RY(-π/2)───────●────────PS(-p9)────────────────────────────────────────────────────────────────────────────────────────────────────────────\n",
+       "
\n" + ], + "text/plain": [ + "q0: ──X────H────●───────────────X────RZ(2*p1)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)─────PS(p4)──────────────────────────────────────────────────────────────────────────────────────────────────────────X────────RZ(2*p6)─────RZ(-π/2)───────●───────────────────────────────────X───────RZ(-π/2)─────PS(p9)─────────────────────────────────────────────────────────────────────────\n", + " │ │ │ │ │ │ │\n", + "q1: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p1)────X────RY(2*p1)────RY(-π/2)────●───────────────────────────X────RZ(2*p3)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────PS(p5)────RZ(π/2)─────────●────────RY(π/2)─────RY(-2*p6)───────X────────RY(2*p6)────RY(-π/2)───────●──────────X────────RZ(2*p8)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────PS(p10)──\n", + " │ │ │ │ │ │\n", + "q2: ──X────H────●───────────────X────RZ(2*p2)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────RZ(π/2)────●────RY(π/2)─────RY(-2*p3)────X────RY(2*p3)────RY(-π/2)────●────PS(-p5)───────X───────RZ(2*p7)─────RZ(-π/2)───────●────────────────────────────────────X────────RZ(-π/2)────RZ(π/2)───────●────────RY(π/2)─────RY(-2*p8)────X────RY(2*p8)────RY(-π/2)────●────PS(-p10)─────────────\n", + " │ │ │ │ │ │ │\n", + "q3: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p2)────X────RY(2*p2)────RY(-π/2)────●────PS(-p4)─────RZ(π/2)──────────────────────────────────────────────────────────────────────────────────●───────RY(π/2)─────RY(-2*p7)───────X─────────RY(2*p7)────RY(-π/2)───────●────────PS(-p9)────────────────────────────────────────────────────────────────────────────────────────────────────────────" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ @@ -240,8 +298,8 @@ " count += 1\n", "\n", "ansatz = encoder + ansatz\n", - "print(ansatz)\n", - "ansatz.summary()" + "ansatz.summary()\n", + "ansatz" ] }, { @@ -253,7 +311,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -392,7 +450,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -418,28 +476,13 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "q0: ──X────H────●───────────────X────RZ(2*p1)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)─────PS(p8)─────────────────────────────────────────────────────────────────────────────────────────────────────────────X─────────RZ(2*p12)─────RZ(-π/2)────────●────────────────────────────────────X───────RZ(-π/2)─────PS(p19)───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────X─────────RZ(2*p23)─────RZ(-π/2)────────●─────────────────────────────────────X─────────RZ(-π/2)──────PS(p30)───────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n", - " │ │ │ │ │ │ │ │ │ │\n", - "q1: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p1)────X────RY(2*p1)────RY(-π/2)────●───────────────────────────X────RZ(2*p5)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)─────PS(p9)──────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p12)───────X────────RY(2*p12)────RY(-π/2)───────●────────────────────────────────────X─────────RZ(2*p16)─────RZ(-π/2)────────●────────────────────────────────────X─────────RZ(-π/2)─────PS(p20)───────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p23)───────X────────RY(2*p23)────RY(-π/2)────────●───────────────────────────────────────X─────────RZ(2*p27)─────RZ(-π/2)────────●────────────────────────────────────X───────RZ(-π/2)────PS(p31)──\n", - " │ │ │ │ │ │ │ │ │\n", - "q2: ──X────H────●───────────────X────RZ(2*p2)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────RZ(π/2)────●────RY(π/2)─────RY(-2*p5)────X────RY(2*p5)────RY(-π/2)────●────PS(p10)──────────────────────────────────X─────────RZ(2*p13)─────RZ(-π/2)────────●────────────────────────────────────X───────RZ(-π/2)─────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p16)───────X────────RY(2*p16)────RY(-π/2)───────●─────────PS(p21)────────────────────────────────────X─────────RZ(2*p24)─────RZ(-π/2)────────●─────────────────────────────────────X─────────RZ(-π/2)──────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p27)───────X────────RY(2*p27)────RY(-π/2)───────●───────PS(p32)──────────────\n", - " │ │ │ │ │ │ │ │ │ │\n", - "q3: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p2)────X────RY(2*p2)────RY(-π/2)────●───────────────────────────X────RZ(2*p6)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────PS(p11)──────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p13)───────X────────RY(2*p13)────RY(-π/2)───────●────────────────────────────────────X─────────RZ(2*p17)─────RZ(-π/2)────────●────────────────────────────────────X─────────RZ(-π/2)─────PS(p22)───────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p24)───────X────────RY(2*p24)────RY(-π/2)────────●────────────X─────────RZ(2*p28)─────RZ(-π/2)─────────●──────────────────────────────────────X────────RZ(-π/2)────PS(p33)─────────────────────────\n", - " │ │ │ │ │ │ │ │ │\n", - "q4: ──X────H────●───────────────X────RZ(2*p3)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────RZ(π/2)────●────RY(π/2)─────RY(-2*p6)────X────RY(2*p6)────RY(-π/2)────●────PS(-p11)─────────────────────────────────X─────────RZ(2*p14)─────RZ(-π/2)────────●────────────────────────────────────X───────RZ(-π/2)─────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p17)───────X────────RY(2*p17)────RY(-π/2)───────●─────────PS(-p22)────────X─────────RZ(2*p25)─────RZ(-π/2)─────────●──────────────────────────────────────X────────RZ(-π/2)─────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p28)────────X────────RY(2*p28)─────RY(-π/2)────────●────────PS(-p33)────────────────────────────────────\n", - " │ │ │ │ │ │ │ │ │ │\n", - "q5: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p3)────X────RY(2*p3)────RY(-π/2)────●───────────────────────────X────RZ(2*p7)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────PS(-p10)─────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p14)───────X────────RY(2*p14)────RY(-π/2)───────●──────────X────────RZ(2*p18)─────RZ(-π/2)─────────●──────────────────────────────────────X────────RZ(-π/2)────PS(-p21)─────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p25)────────X────────RY(2*p25)─────RY(-π/2)────────●───────────X────────RZ(2*p29)─────RZ(-π/2)─────────●───────────────────────────────────────X─────────RZ(-π/2)─────PS(-p32)────────────────────────────────────────────────\n", - " │ │ │ │ │ │ │ │ │\n", - "q6: ──X────H────●───────────────X────RZ(2*p4)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────RZ(π/2)────●────RY(π/2)─────RY(-2*p7)────X────RY(2*p7)────RY(-π/2)────●────PS(-p9)────────X────────RZ(2*p15)─────RZ(-π/2)─────────●──────────────────────────────────────X────────RZ(-π/2)────RZ(π/2)───────●─────────RY(π/2)─────RY(-2*p18)────────X────────RY(2*p18)─────RY(-π/2)────────●────────PS(-p20)───────X────────RZ(2*p26)─────RZ(-π/2)─────────●───────────────────────────────────────X─────────RZ(-π/2)─────RZ(π/2)────────●─────────RY(π/2)─────RY(-2*p29)────────X────────RY(2*p29)──────RY(-π/2)────────●─────────PS(-p31)─────────────────────────────────────────────────────────────\n", - " │ │ │ │ │ │ │ │ │ │\n", - "q7: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p4)────X────RY(2*p4)────RY(-π/2)────●────PS(-p8)─────RZ(π/2)───────────────────────────────────────────────────────────────────────────────────●─────────RY(π/2)─────RY(-2*p15)────────X────────RY(2*p15)─────RY(-π/2)────────●────────PS(-p19)────RZ(π/2)──────────────────────────────────────────────────────────────────────────────────────────────────────────────●─────────RY(π/2)─────RY(-2*p26)────────X────────RY(2*p26)──────RY(-π/2)────────●─────────PS(-p30)───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n", "===========================Circuit Summary===========================\n", "|Total number of gates : 271. |\n", "|Parameter gates : 87. |\n", @@ -468,6 +511,58 @@ "1 [Y6 Y7] +\n", "1 [Z6 Z7] \n" ] + }, + { + "data": { + "text/html": [ + "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "
q0: ──X────H────●───────────────X────RZ(2*p1)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)─────PS(p8)─────────────────────────────────────────────────────────────────────────────────────────────────────────────X─────────RZ(2*p12)─────RZ(-π/2)────────●────────────────────────────────────X───────RZ(-π/2)─────PS(p19)───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────X─────────RZ(2*p23)─────RZ(-π/2)────────●─────────────────────────────────────X─────────RZ(-π/2)──────PS(p30)───────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n",
+       "                │               │                             │                            │                                                                                                                                    │                                       │                                    │                                                                                                                                                                      │                                       │                                     │\n",
+       "q1: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p1)────X────RY(2*p1)────RY(-π/2)────●───────────────────────────X────RZ(2*p5)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)─────PS(p9)──────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p12)───────X────────RY(2*p12)────RY(-π/2)───────●────────────────────────────────────X─────────RZ(2*p16)─────RZ(-π/2)────────●────────────────────────────────────X─────────RZ(-π/2)─────PS(p20)───────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p23)───────X────────RY(2*p23)────RY(-π/2)────────●───────────────────────────────────────X─────────RZ(2*p27)─────RZ(-π/2)────────●────────────────────────────────────X───────RZ(-π/2)────PS(p31)──\n",
+       "                                                                                                                       │                             │                            │                                                                                                                                                               │                                       │                                    │                                                                                                                                                                          │                                       │                                    │\n",
+       "q2: ──X────H────●───────────────X────RZ(2*p2)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────RZ(π/2)────●────RY(π/2)─────RY(-2*p5)────X────RY(2*p5)────RY(-π/2)────●────PS(p10)──────────────────────────────────X─────────RZ(2*p13)─────RZ(-π/2)────────●────────────────────────────────────X───────RZ(-π/2)─────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p16)───────X────────RY(2*p16)────RY(-π/2)───────●─────────PS(p21)────────────────────────────────────X─────────RZ(2*p24)─────RZ(-π/2)────────●─────────────────────────────────────X─────────RZ(-π/2)──────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p27)───────X────────RY(2*p27)────RY(-π/2)───────●───────PS(p32)──────────────\n",
+       "                │               │                             │                            │                                                                                                                                    │                                       │                                    │                                                                                                                                                                      │                                       │                                     │\n",
+       "q3: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p2)────X────RY(2*p2)────RY(-π/2)────●───────────────────────────X────RZ(2*p6)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────PS(p11)──────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p13)───────X────────RY(2*p13)────RY(-π/2)───────●────────────────────────────────────X─────────RZ(2*p17)─────RZ(-π/2)────────●────────────────────────────────────X─────────RZ(-π/2)─────PS(p22)───────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p24)───────X────────RY(2*p24)────RY(-π/2)────────●────────────X─────────RZ(2*p28)─────RZ(-π/2)─────────●──────────────────────────────────────X────────RZ(-π/2)────PS(p33)─────────────────────────\n",
+       "                                                                                                                       │                             │                            │                                                                                                                                                               │                                       │                                    │                                                                                                                                               │                                        │                                      │\n",
+       "q4: ──X────H────●───────────────X────RZ(2*p3)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────RZ(π/2)────●────RY(π/2)─────RY(-2*p6)────X────RY(2*p6)────RY(-π/2)────●────PS(-p11)─────────────────────────────────X─────────RZ(2*p14)─────RZ(-π/2)────────●────────────────────────────────────X───────RZ(-π/2)─────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p17)───────X────────RY(2*p17)────RY(-π/2)───────●─────────PS(-p22)────────X─────────RZ(2*p25)─────RZ(-π/2)─────────●──────────────────────────────────────X────────RZ(-π/2)─────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p28)────────X────────RY(2*p28)─────RY(-π/2)────────●────────PS(-p33)────────────────────────────────────\n",
+       "                │               │                             │                            │                                                                                                                                    │                                       │                                    │                                                                                                                                           │                                        │                                      │\n",
+       "q5: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p3)────X────RY(2*p3)────RY(-π/2)────●───────────────────────────X────RZ(2*p7)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────PS(-p10)─────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p14)───────X────────RY(2*p14)────RY(-π/2)───────●──────────X────────RZ(2*p18)─────RZ(-π/2)─────────●──────────────────────────────────────X────────RZ(-π/2)────PS(-p21)─────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p25)────────X────────RY(2*p25)─────RY(-π/2)────────●───────────X────────RZ(2*p29)─────RZ(-π/2)─────────●───────────────────────────────────────X─────────RZ(-π/2)─────PS(-p32)────────────────────────────────────────────────\n",
+       "                                                                                                                       │                             │                            │                                                                                                                                     │                                       │                                      │                                                                                                                                             │                                       │                                       │\n",
+       "q6: ──X────H────●───────────────X────RZ(2*p4)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────RZ(π/2)────●────RY(π/2)─────RY(-2*p7)────X────RY(2*p7)────RY(-π/2)────●────PS(-p9)────────X────────RZ(2*p15)─────RZ(-π/2)─────────●──────────────────────────────────────X────────RZ(-π/2)────RZ(π/2)───────●─────────RY(π/2)─────RY(-2*p18)────────X────────RY(2*p18)─────RY(-π/2)────────●────────PS(-p20)───────X────────RZ(2*p26)─────RZ(-π/2)─────────●───────────────────────────────────────X─────────RZ(-π/2)─────RZ(π/2)────────●─────────RY(π/2)─────RY(-2*p29)────────X────────RY(2*p29)──────RY(-π/2)────────●─────────PS(-p31)─────────────────────────────────────────────────────────────\n",
+       "                │               │                             │                            │                                                                                                          │                                       │                                      │                                                                                                                                         │                                       │                                       │\n",
+       "q7: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p4)────X────RY(2*p4)────RY(-π/2)────●────PS(-p8)─────RZ(π/2)───────────────────────────────────────────────────────────────────────────────────●─────────RY(π/2)─────RY(-2*p15)────────X────────RY(2*p15)─────RY(-π/2)────────●────────PS(-p19)────RZ(π/2)──────────────────────────────────────────────────────────────────────────────────────────────────────────────●─────────RY(π/2)─────RY(-2*p26)────────X────────RY(2*p26)──────RY(-π/2)────────●─────────PS(-p30)───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n",
+       "
\n" + ], + "text/plain": [ + "q0: ──X────H────●───────────────X────RZ(2*p1)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)─────PS(p8)─────────────────────────────────────────────────────────────────────────────────────────────────────────────X─────────RZ(2*p12)─────RZ(-π/2)────────●────────────────────────────────────X───────RZ(-π/2)─────PS(p19)───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────X─────────RZ(2*p23)─────RZ(-π/2)────────●─────────────────────────────────────X─────────RZ(-π/2)──────PS(p30)───────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n", + " │ │ │ │ │ │ │ │ │ │\n", + "q1: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p1)────X────RY(2*p1)────RY(-π/2)────●───────────────────────────X────RZ(2*p5)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)─────PS(p9)──────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p12)───────X────────RY(2*p12)────RY(-π/2)───────●────────────────────────────────────X─────────RZ(2*p16)─────RZ(-π/2)────────●────────────────────────────────────X─────────RZ(-π/2)─────PS(p20)───────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p23)───────X────────RY(2*p23)────RY(-π/2)────────●───────────────────────────────────────X─────────RZ(2*p27)─────RZ(-π/2)────────●────────────────────────────────────X───────RZ(-π/2)────PS(p31)──\n", + " │ │ │ │ │ │ │ │ │\n", + "q2: ──X────H────●───────────────X────RZ(2*p2)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────RZ(π/2)────●────RY(π/2)─────RY(-2*p5)────X────RY(2*p5)────RY(-π/2)────●────PS(p10)──────────────────────────────────X─────────RZ(2*p13)─────RZ(-π/2)────────●────────────────────────────────────X───────RZ(-π/2)─────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p16)───────X────────RY(2*p16)────RY(-π/2)───────●─────────PS(p21)────────────────────────────────────X─────────RZ(2*p24)─────RZ(-π/2)────────●─────────────────────────────────────X─────────RZ(-π/2)──────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p27)───────X────────RY(2*p27)────RY(-π/2)───────●───────PS(p32)──────────────\n", + " │ │ │ │ │ │ │ │ │ │\n", + "q3: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p2)────X────RY(2*p2)────RY(-π/2)────●───────────────────────────X────RZ(2*p6)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────PS(p11)──────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p13)───────X────────RY(2*p13)────RY(-π/2)───────●────────────────────────────────────X─────────RZ(2*p17)─────RZ(-π/2)────────●────────────────────────────────────X─────────RZ(-π/2)─────PS(p22)───────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p24)───────X────────RY(2*p24)────RY(-π/2)────────●────────────X─────────RZ(2*p28)─────RZ(-π/2)─────────●──────────────────────────────────────X────────RZ(-π/2)────PS(p33)─────────────────────────\n", + " │ │ │ │ │ │ │ │ │\n", + "q4: ──X────H────●───────────────X────RZ(2*p3)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────RZ(π/2)────●────RY(π/2)─────RY(-2*p6)────X────RY(2*p6)────RY(-π/2)────●────PS(-p11)─────────────────────────────────X─────────RZ(2*p14)─────RZ(-π/2)────────●────────────────────────────────────X───────RZ(-π/2)─────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p17)───────X────────RY(2*p17)────RY(-π/2)───────●─────────PS(-p22)────────X─────────RZ(2*p25)─────RZ(-π/2)─────────●──────────────────────────────────────X────────RZ(-π/2)─────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p28)────────X────────RY(2*p28)─────RY(-π/2)────────●────────PS(-p33)────────────────────────────────────\n", + " │ │ │ │ │ │ │ │ │ │\n", + "q5: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p3)────X────RY(2*p3)────RY(-π/2)────●───────────────────────────X────RZ(2*p7)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────PS(-p10)─────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p14)───────X────────RY(2*p14)────RY(-π/2)───────●──────────X────────RZ(2*p18)─────RZ(-π/2)─────────●──────────────────────────────────────X────────RZ(-π/2)────PS(-p21)─────RZ(π/2)─────────●──────────RY(π/2)─────RY(-2*p25)────────X────────RY(2*p25)─────RY(-π/2)────────●───────────X────────RZ(2*p29)─────RZ(-π/2)─────────●───────────────────────────────────────X─────────RZ(-π/2)─────PS(-p32)────────────────────────────────────────────────\n", + " │ │ │ │ │ │ │ │ │\n", + "q6: ──X────H────●───────────────X────RZ(2*p4)─────RZ(-π/2)────●────────────────────────────X────RZ(-π/2)────RZ(π/2)────●────RY(π/2)─────RY(-2*p7)────X────RY(2*p7)────RY(-π/2)────●────PS(-p9)────────X────────RZ(2*p15)─────RZ(-π/2)─────────●──────────────────────────────────────X────────RZ(-π/2)────RZ(π/2)───────●─────────RY(π/2)─────RY(-2*p18)────────X────────RY(2*p18)─────RY(-π/2)────────●────────PS(-p20)───────X────────RZ(2*p26)─────RZ(-π/2)─────────●───────────────────────────────────────X─────────RZ(-π/2)─────RZ(π/2)────────●─────────RY(π/2)─────RY(-2*p29)────────X────────RY(2*p29)──────RY(-π/2)────────●─────────PS(-p31)─────────────────────────────────────────────────────────────\n", + " │ │ │ │ │ │ │ │ │ │\n", + "q7: ──X─────────X────RZ(π/2)────●────RY(π/2)─────RY(-2*p4)────X────RY(2*p4)────RY(-π/2)────●────PS(-p8)─────RZ(π/2)───────────────────────────────────────────────────────────────────────────────────●─────────RY(π/2)─────RY(-2*p15)────────X────────RY(2*p15)─────RY(-π/2)────────●────────PS(-p19)────RZ(π/2)──────────────────────────────────────────────────────────────────────────────────────────────────────────────●─────────RY(π/2)─────RY(-2*p26)────────X────────RY(2*p26)──────RY(-π/2)────────●─────────PS(-p30)───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ @@ -494,7 +589,6 @@ " count += 1\n", "\n", "ansatz = encoder + ansatz\n", - "print(ansatz)\n", "ansatz.summary()\n", "\n", "J = 1\n", @@ -505,7 +599,8 @@ " ham += QubitOperator('Z%d Z%d' % (i, i + 1), J)\n", "ham = Hamiltonian(ham - QubitOperator(''))\n", "\n", - "print(ham)" + "print(ham)\n", + "ansatz" ] }, { -- Gitee