{ "cells": [ { "cell_type": "markdown", "id": "681e955a", "metadata": {}, "source": [ "# 量子线路高阶操作\n", "\n", "[![下载Notebook](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.0.0-alpha/resource/_static/logo_notebook.png)](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/r2.0.0-alpha/mindquantum/zh_cn/mindspore_advanced_operations_of_quantum_circuit.ipynb) \n", "[![下载样例代码](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.0.0-alpha/resource/_static/logo_download_code.png)](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/r2.0.0-alpha/mindquantum/zh_cn/mindspore_advanced_operations_of_quantum_circuit.py) \n", "[![查看源文件](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.0.0-alpha/resource/_static/logo_source.png)](https://gitee.com/mindspore/docs/blob/r2.0.0-alpha/docs/mindquantum/docs/source_zh_cn/advanced_operations_of_quantum_circuit.ipynb) \n", "[![在ModelArts平台运行](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.0.0-alpha/resource/_static/logo_modelarts.png)](https://authoring-modelarts-cnnorth4.huaweicloud.com/console/lab?share-url-b64=aHR0cHM6Ly9taW5kc3BvcmUtd2Vic2l0ZS5vYnMuY24tbm9ydGgtNC5teWh1YXdlaWNsb3VkLmNvbS9ub3RlYm9vay9yMi4wLjAtYWxwaGEvbWluZHF1YW50dW0vemhfY24vbWluZHNwb3JlX2FkdmFuY2VkX29wZXJhdGlvbnNfb2ZfcXVhbnR1bV9jaXJjdWl0LmlweW5i&imageid=b711ac95-db2b-45b7-ab9b-98de275dd57e)\n", "\n", "在前面变分量子线路操作指导中介绍了 量子线路 的基本用法。接下来,我们将进一步探索MindQuantum为量子线路定义的一些高阶操作的用法。\n", "\n", "## mindquantum.core.circuit.controlled\n", "\n", "controlled方法用于对任意量子线路或量子算符添加控制量子比特(可以是多个)。\n", "\n", "例如,我们构建一个仅包含两个量子比特的量子线路,并通过controlled方法对其添加一个控制量子比特——$q_2$:" ] }, { "cell_type": "code", "execution_count": 1, "id": "c44755ab", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": "\n\n\nq0:\n \n\nq1:\n \n\n\n\n\n\nH\n \n\n\n\n\n\nPS\n \n\nπ/2\n \n\n\n\n\nH\n \n\n\n\n\n\n\n\n\n\n", "text/plain": [ "" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from mindquantum.algorithm.library import qft\n", "from mindquantum.core.circuit import controlled\n", "\n", "u1 = qft(range(2)) # 构建量子线路\n", "u1.svg()" ] }, { "cell_type": "code", "execution_count": 2, "id": "9330f35e", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": "\n\n\nq0:\n \n\nq1:\n \n\nq2:\n \n\n\n\n\n\n\n\nH\n \n\n\n\n\n\n\nPS\n \n\nπ/2\n \n\n\n\n\n\nH\n \n\n\n\n\n\n\n\n\n\n\n", "text/plain": [ "" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "u2 = controlled(u1)(2) # 对线路添加控制量子位q2,返回一个新的线路\n", "u2.svg()" ] }, { "cell_type": "markdown", "id": "4d63b2ef", "metadata": {}, "source": [ "实际上,controlled()返回的是一个函数。例如:" ] }, { "cell_type": "code", "execution_count": 3, "id": "6144080f", "metadata": {}, "outputs": [], "source": [ "u3 = controlled(u1)" ] }, { "cell_type": "markdown", "id": "3c2a5acf", "metadata": {}, "source": [ "我们可通过调用u3来对初始线路u1添加控制量子位,和上面的效果是一样的:" ] }, { "cell_type": "code", "execution_count": 4, "id": "39a3af2d", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": "\n\n\nq0:\n \n\nq1:\n \n\nq2:\n \n\n\n\n\n\n\n\nH\n \n\n\n\n\n\n\nPS\n \n\nπ/2\n \n\n\n\n\n\nH\n \n\n\n\n\n\n\n\n\n\n\n", "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "u4 = u3(2)\n", "u4.svg()" ] }, { "cell_type": "markdown", "id": "5381a350", "metadata": {}, "source": [ "注意:添加的控制量子比特不能是线路中已存在的某个门的目标量子比特,否则会报错!\n", "\n", "另外,我们还可以对量子线路批量添加控制位。例如,在下面的示例中,我们对$q_0$和$q_1$分别添加控制位——$q_2$和$q_3$:" ] }, { "cell_type": "code", "execution_count": 5, "id": "bb5e74ff", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": "\n\n\nq0:\n \n\nq1:\n \n\nq2:\n \n\nq3:\n \n\n\n\n\n\n\n\n\n\nH\n \n\n\n\n\n\n\n\nPS\n \n\nπ/2\n \n\n\n\n\n\n\nH\n \n\n\n\n\n\n\n\n\n\n\n\n", "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "u = controlled(qft)\n", "u = u([2, 3], [0, 1]) # 批量添加控制位\n", "u.svg()" ] }, { "cell_type": "markdown", "id": "f991b869", "metadata": {}, "source": [ "## mindquantum.core.circuit.dagger\n", "\n", "dagger方法用于求量子线路或量子算符的厄米共轭。\n", "\n", "以下示例提供了两种进行dagger操作的方式:" ] }, { "cell_type": "code", "execution_count": 6, "id": "7d203008", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": "\n\n\nq0:\n \n\nq1:\n \n\nq2:\n \n\n\n\n\n\n\nH\n \n\n\n\n\n\nPS\n \n\nπ/2\n \n\n\n\n\n\nPS\n \n\nπ/4\n \n\n\n\n\nH\n \n\n\n\n\n\nPS\n \n\nπ/2\n \n\n\n\n\nH\n \n\n\n\n\n\n\n\n\n\n", "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from mindquantum.core.circuit import dagger\n", "\n", "u1 = qft(range(3))\n", "u1.svg()" ] }, { "cell_type": "code", "execution_count": 7, "id": "1229c41f", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": "\n\n\nq0:\n \n\nq1:\n \n\nq2:\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\nH\n \n\n\n\n\n\nPS\n \n\n-π/2\n \n\n\n\n\nH\n \n\n\n\n\n\nPS\n \n\n-π/4\n \n\n\n\n\n\nPS\n \n\n-π/2\n \n\n\n\n\nH\n \n\n", "text/plain": [ "" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "u2 = dagger(u1)\n", "u2.svg()" ] }, { "cell_type": "code", "execution_count": 8, "id": "26239556", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": "\n\n\nq0:\n \n\nq1:\n \n\nq2:\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\nH\n \n\n\n\n\n\nPS\n \n\n-π/2\n \n\n\n\n\nH\n \n\n\n\n\n\nPS\n \n\n-π/4\n \n\n\n\n\n\nPS\n \n\n-π/2\n \n\n\n\n\nH\n \n\n", "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "u3 = dagger(qft)\n", "u4 = u3(range(3))\n", "u4.svg()" ] }, { "cell_type": "markdown", "id": "69117023", "metadata": {}, "source": [ "可看到,两种方式得到的线路是相同的。\n", "\n", "## mindquantum.core.circuit.apply\n", "\n", "apply方法用于将量子线路或量子算符作用在指定的量子比特(可以是多个)上。" ] }, { "cell_type": "code", "execution_count": 9, "id": "865da650", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": "\n\n\nq0:\n \n\nq1:\n \n\n\n\n\n\nH\n \n\n\n\n\n\nPS\n \n\nπ/2\n \n\n\n\n\nH\n \n\n\n\n\n\n\n\n\n\n", "text/plain": [ "" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from mindquantum.core.circuit import apply\n", "\n", "u1 = qft([0, 1])\n", "circuit1 = apply(u1, [1, 0]) # 将量子线路u1作用在比特q1, q0上\n", "circuit1.svg()" ] }, { "cell_type": "code", "execution_count": 10, "id": "67ed697a", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": "\n\n\nq0:\n \n\nq1:\n \n\n\n\n\n\nH\n \n\n\n\n\n\nPS\n \n\nπ/2\n \n\n\n\n\nH\n \n\n\n\n\n\n\n\n\n\n", "text/plain": [ "" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "u2 = apply(qft, [1, 0]) # 将qft作用在比特q0, q1上\n", "circuit2 = u2([0, 1])\n", "circuit2.svg()" ] }, { "cell_type": "markdown", "id": "553beec8", "metadata": {}, "source": [ "## mindquantum.core.circuit.add_prefix\n", "\n", "add_prefix方法用于在参数化量子电路或参数化量子算符的参数名上加上前缀。这在神经网络分层中十分有用,例如:" ] }, { "cell_type": "code", "execution_count": 11, "id": "5c70b2f8", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": "\n\n\nq0:\n \n\n\n\n\nRX\n \n\ntheta\n \n\n", "text/plain": [ "" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from mindquantum.core.circuit import add_prefix, Circuit\n", "from mindquantum.core.gates import RX, H\n", "\n", "circ = Circuit().rx(\"theta\", 0)\n", "circ.svg()" ] }, { "cell_type": "code", "execution_count": 12, "id": "3ecfc597", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": "\n\n\nq0:\n \n\n\n\n\nRX\n \n\nl0_theta\n \n\n", "text/plain": [ "" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "circ = add_prefix(circ, 'l0') # 添加后,参数\"theta\"就变成了\"l0_theta\"\n", "circ.svg()" ] }, { "cell_type": "markdown", "id": "e3c09fbc", "metadata": {}, "source": [ "我们可以在含参量子门作用于具体的量子比特后对其参数名称添加前缀,也可以在其还未应用于量子比特的时候添加。例如:" ] }, { "cell_type": "code", "execution_count": 13, "id": "71f56c75", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": "\n\n\nq0:\n \n\n\n\n\nH\n \n\n\n\n\nRX\n \n\nansatz_a\n \n\n", "text/plain": [ "" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "u = lambda qubit: Circuit([H.on(0), RX('a').on(qubit)])\n", "\n", "u1 = u(0)\n", "u1 = add_prefix(u1, 'ansatz')\n", "u1.svg()" ] }, { "cell_type": "code", "execution_count": 14, "id": "edbf7b03", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": "\n\n\nq0:\n \n\n\n\n\nH\n \n\n\n\n\nRX\n \n\nansatz_a\n \n\n", "text/plain": [ "" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "u2 = add_prefix(u, 'ansatz')\n", "u2 = u2(0)\n", "u2.svg()" ] }, { "cell_type": "markdown", "id": "c05a8195", "metadata": {}, "source": [ "## mindquantum.core.circuit.change_param_name\n", "\n", "change_param_name方法用于修改参数化量子电路或参数化量子算符的参数名。" ] }, { "cell_type": "code", "execution_count": 15, "id": "d844ba22", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": "\n\n\nq0:\n \n\n\n\n\nH\n \n\n\n\n\nRX\n \n\nb\n \n\n", "text/plain": [ "" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from mindquantum.core.circuit import change_param_name, Circuit\n", "from mindquantum.core.gates import RX, H\n", "\n", "u = lambda qubit: Circuit([H.on(0), RX('a').on(qubit)])\n", "\n", "u1 = u(0)\n", "u1 = change_param_name(u1, {'a': 'b'})\n", "u1.svg()" ] }, { "cell_type": "code", "execution_count": 16, "id": "3a1d5d5f", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": "\n\n\nq0:\n \n\n\n\n\nH\n \n\n\n\n\nRX\n \n\nb\n \n\n", "text/plain": [ "" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "u2 = change_param_name(u, {'a': 'b'})\n", "u2 = u2(0)\n", "u2.svg()" ] }, { "cell_type": "markdown", "id": "522ec9fc", "metadata": {}, "source": [ "## mindquantum.core.circuit.UN\n", "\n", "UN模块用于将量子门作用于不同的目标量子比特和控制量子比特。\n", "\n", "一般格式如下:mindquantum.circuit.UN(gate, maps_obj, maps_ctrl=None),参数gate是要执行的量子门,maps_obj是需要执行该量子门的目标量子比特,maps_ctrl是控制量子比特(无控制量子位时为None)。若每个量子比特位都执行同一不含参的量子门,则可以直接使用UN(gate, N),N表示量子比特个数。\n", "\n", "以下是一个简单的示例,我们在构建的线路中对每一位量子比特都应用一个H门:" ] }, { "cell_type": "code", "execution_count": 17, "id": "6ba3b3ff", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": "\n\n\nq0:\n \n\nq1:\n \n\nq2:\n \n\nq3:\n \n\n\n\n\n\n\n\nH\n \n\n\n\n\nH\n \n\n\n\n\nH\n \n\n\n\n\nH\n \n\n", "text/plain": [ "" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from mindquantum.core.circuit import change_param_name, Circuit, UN\n", "from mindquantum.core.gates import X, H, SWAP\n", "\n", "circuit1 = Circuit()\n", "circuit1 += UN(H, 4) # 将H门作用在每一位量子比特上\n", "circuit1.svg()" ] }, { "cell_type": "markdown", "id": "52a24be7", "metadata": {}, "source": [ "以下示例中,我们对量子比特$q_2$和$q_0$、$q_3$和$q_1$分别添加一个CNOT门,其中$q_2$为控制位,$q_0$为目标位;$q_3$为控制位,$q_1$为目标位:" ] }, { "cell_type": "code", "execution_count": 18, "id": "3fbb0af7", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": "\n\n\nq0:\n \n\nq1:\n \n\nq2:\n \n\nq3:\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", "text/plain": [ "" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "circuit2 = UN(X, maps_obj=[0, 1], maps_ctrl=[2, 3])\n", "circuit2.svg()" ] }, { "cell_type": "markdown", "id": "e44d378e", "metadata": {}, "source": [ "针对类似SWAP的门的用法如下:" ] }, { "cell_type": "code", "execution_count": 19, "id": "2ccd1cf8", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": "\n\n\nq0:\n \n\nq1:\n \n\nq2:\n \n\nq3:\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", "text/plain": [ "" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "circuit3 = UN(SWAP, maps_obj=[[0, 1], [2, 3]]).x(2, 1)\n", "circuit3.svg()" ] }, { "cell_type": "markdown", "id": "9b0d1910", "metadata": {}, "source": [ "## mindquantum.core.circuit.shift\n", "\n", "shift方法用于修改给定线路的量子位范围,参数为要挪动的步长。注意,步长不能为负数。并且,只能挪到最后一个量子比特,不能循环到$q_0$(第一个量子位)。" ] }, { "cell_type": "code", "execution_count": 20, "id": "71d000ca", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": "\n\n\nq0:\n \n\nq1:\n \n\n\n\n\n\n\n\n", "text/plain": [ "" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from mindquantum.core.circuit import shift, Circuit\n", "from mindquantum.core.gates import X\n", "\n", "circ = Circuit().x(1, 0)\n", "circ.svg()" ] }, { "cell_type": "code", "execution_count": 21, "id": "180fde8c", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": "\n\n\nq1:\n \n\nq2:\n \n\n\n\n\n\n\n\n", "text/plain": [ "" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "circ = shift(circ, 1)\n", "circ.svg() # 线路作用的量子比特从q0,q1变为q1,q2" ] }, { "cell_type": "markdown", "id": "b5050bd9", "metadata": {}, "source": [ "### 案例——鸢尾花分类:搭建Encoder\n", "\n", "以上高阶操作的示例显示了量子线路高阶操作的适用性及便捷性,如果我们进一步将它们组合起来用于构建量子线路,又会产生什么神奇魔力呢?\n", "\n", "接下来我们将以 通过量子神经网络对鸢尾花进行分类\n", " 的案例中 搭建Encoder 部分为例,搭建下图所示的量子线路:\n", "\n", "![encoder classification of iris by qnn](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.0.0-alpha/docs/mindquantum/docs/source_zh_cn/images/encoder_classification_of_iris_by_qnn.png)\n" ] }, { "cell_type": "code", "execution_count": 22, "id": "89bbaf78", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "=====================================Circuit Summary=====================================\n", "|Total number of gates : 17. |\n", "|Parameter gates : 7. |\n", "|with 7 parameters are : 0_alpha, 1_alpha, 2_alpha, 3_alpha, 4_alpha, 5_alpha, 6_alpha.|\n", "|Number qubit of circuit: 4 |\n", "=========================================================================================\n" ] } ], "source": [ "from mindquantum.core.circuit import shift, add_prefix, Circuit, UN\n", "from mindquantum.core.gates import RZ, X, H\n", "\n", "template = Circuit([X.on(1, 0), RZ('alpha').on(1), X.on(1, 0)])\n", "encoder = UN(H, 4) + (RZ(f'{i}_alpha').on(i) for i in range(4)) + sum(add_prefix(shift(template, i), f'{i+4}') for i in range(3))\n", "encoder.summary()" ] }, { "cell_type": "code", "execution_count": 23, "id": "1686faa1", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": "\n\n\nq0:\n \n\nq1:\n \n\nq2:\n \n\nq3:\n \n\n\n\n\n\n\n\nH\n \n\n\n\n\nH\n \n\n\n\n\nH\n \n\n\n\n\nH\n \n\n\n\n\nRZ\n \n\n0_alpha\n \n\n\n\n\nRZ\n \n\n1_alpha\n \n\n\n\n\nRZ\n \n\n2_alpha\n \n\n\n\n\nRZ\n \n\n3_alpha\n \n\n\n\n\n\n\n\n\n\nRZ\n \n\n4_alpha\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\nRZ\n \n\n5_alpha\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\nRZ\n \n\n6_alpha\n \n\n\n\n\n\n\n", "text/plain": [ "" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "encoder.svg()" ] }, { "cell_type": "markdown", "id": "8dcb676b", "metadata": {}, "source": [ "在上面的代码中,我们使用UN模块将不含参数的H门作用于目标量子比特$q_0$~$q_3$,然后将RZ(i_alpha)门作用于第i位量子比特。\n", "接着,观察到线路中有三个一样的模块,它们都由一个受控X门、一个RZ门和一个受控X门构成,因此,我们构造对应的模板template,它由一个受$q_0$控制、作用在$q_1$的X门,一个作用在$q_1$的RZ门和一个受$q_0$控制、作用在$q_1$的X门构成。然后我们通过shift(template, i)来改变模板作用的量子比特范围,构建三个结构相同但作用的量子比特范围相差1的模块,其涉及的量子比特范围分别为$q_0$和$q_1$、$q_1$和$q_2$、$q_2$和$q_3$。\n", "最后,我们使用add_prefix方法为通过shift构造的所有含参量子门的参数名加上一个数字前缀。\n", "\n", "至此,通过MindQuantum提供的这些量子线路高阶操作,我们仅用两行代码就构建了所需的Encoder!\n", "\n", "若想查询更多关于MindQuantum的API,请点击:[https://mindspore.cn/mindquantum/](https://mindspore.cn/mindquantum/)。" ] } ], "metadata": { "kernelspec": { "display_name": "MindSpore", "language": "python", "name": "mindspore" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.8" } }, "nbformat": 4, "nbformat_minor": 5 }