diff --git a/images/Deutsch_Jozsa_algorithm.png b/images/Deutsch_Jozsa_algorithm.png new file mode 100644 index 0000000000000000000000000000000000000000..e04d82858e0b3c2fa55aa9a8c5c0539bbeb5dcfb Binary files /dev/null and b/images/Deutsch_Jozsa_algorithm.png differ diff --git a/images/NAND_gate.png b/images/NAND_gate.png new file mode 100644 index 0000000000000000000000000000000000000000..7456556f1873103f81d10e46121bd46534776afc Binary files /dev/null and b/images/NAND_gate.png differ diff --git a/images/NAND_logic_table.png b/images/NAND_logic_table.png new file mode 100644 index 0000000000000000000000000000000000000000..d2df34b678af169e1fd784885699bfc456d3636b Binary files /dev/null and b/images/NAND_logic_table.png differ diff --git a/images/Schatten_norms.png b/images/Schatten_norms.png new file mode 100644 index 0000000000000000000000000000000000000000..99fea25c9daeb9f126d09b5358aa143423ba1208 Binary files /dev/null and b/images/Schatten_norms.png differ diff --git a/images/Toffoli_logic_table.png b/images/Toffoli_logic_table.png new file mode 100644 index 0000000000000000000000000000000000000000..f87d15e195400e611d48da340994ab56f01ae3fd Binary files /dev/null and b/images/Toffoli_logic_table.png differ diff --git a/lecture17.ipynb b/lecture17.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..ec39121331d34158c251d833b9eae1c159076632 --- /dev/null +++ b/lecture17.ipynb @@ -0,0 +1,129 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Lecture 17\n", + "\n", + "## Solovay-Kitaev 算法\n", + "现在,我们已经了解到,使用 THTH 序列之类的东西,我们可以将任何单个量子比特门逼近到任何精度,但是性能似乎很差。Solovay-Kitaev 算法旨在加快逼近门的过程。SK 算法的适用性比我们先前所讨论的要广泛,因此,我们需要学习$\\epsilon$-net 的概念。什么是$\\epsilon$-net $V_\\epsilon$?我们已经见过一个(在上一节的最后一个等式中)。简单来说,给定一个任意的酉门,如果我们有一个 $\\epsilon$-net,那么我们应该能够用某个门$V\\in V_\\epsilon$来近似$U$,精度为$\\epsilon$,即\n", + "$$\n", + "\\boxed{\n", + "\\|U-V\\| \\equiv \\operatorname{tr} \\sqrt{(U-V)^{\\dagger}(U-V)} \\leq \\epsilon\n", + "}\n", + "$$\n", + "上式等价于$\\left\\|U V^{+}-I\\right\\| \\leq \\epsilon$。\n", + "\n", + "**此外,逆应当存在,即如果我们有$V$, 则我们有$V^\\dagger$。**\n", + "\n", + "让我们仔细研究对于一个任意矩阵的(迹)范数:$\\|A\\|=\\operatorname{tr}\\sqrt{A^\\dagger A}$\n", + "\n", + "- 若$A$是厄米的,即$A^\\dagger=A$,那么$\\|A\\|=\\left|a_{1}\\right|+\\left|a_{2}\\right|+\\left|a_{3}\\right|+\\ldots$是特征值的绝对值之和。\n", + "\n", + "- 对于任何幺正矩阵$U$,$\\|U A\\|=\\operatorname{tr}\\sqrt{A^\\dagger U^\\dagger U A}=\\|A\\|$。\n", + "\n", + "也可以参考\n", + "\n", + "![Schatten norms](images/Schatten_norms.png)\n", + "\n", + "我们要做的是从 $\\epsilon$-net 构造一个更精确的近似值 $\\epsilon^{3/2}=\\epsilon \\cdot \\epsilon^{1/2}<\\epsilon$。\n", + "$$\n", + "\\boxed{\n", + "\\left\\|U V^{\\dagger}-W\\right\\|=\\|U-W V\\|=O\\left(\\epsilon^{3 / 2}\\right)\n", + "}\n", + "$$\n", + "其中$W$是 epsilon 网络中门的**乘积**。这是一个令人惊讶的结果,通常我们认为近似值应该是$O\\left(\\epsilon\\right)$。\n", + "\n", + "- 如果每一步都花费$O\\left(\\epsilon\\right)$,n 步将是$O\\left(n \\epsilon\\right)$\n", + "- 请记住,这里的错误是**系统性**的,这意味着它无法被消除。\n", + "\n", + "---\n", + "\n", + "**证明**\n", + "\n", + "- 首先,让我们定义(你总是可以这样做)\n", + "$$\n", + "U V^\\dagger \\equiv e^{iA}\n", + "$$\n", + "其中我们有 $\\|A\\| = O(\\epsilon)$,且$\\|e^{iA}-I\\|=\\|iA\\|=O(\\epsilon)$。等价的,我们可以只写$A=O(\\epsilon)$。\n", + "\n", + "- 接下来,我们要找到一个记为$W$的门的乘积,以最小化范数:$\\|U V^\\dagger - W\\|=\\|e^{iA} - W\\|$。为了继续,我们需要知道一个有趣的关系:对于任何给定的$A$,总是可以找到一对(它们可能不是唯一的)矩阵$B$和$C$使得\n", + "$$\n", + "[B, C]=-iA\n", + "$$\n", + "其中$\\|B\\|=\\|C\\|=O(\\epsilon^{1/2})$。\n", + "\n", + "- 对于量子比特,你可以想象我们可以旋转参考系,因此$A = O(\\epsilon)Z$。那么,自然地,我们可以选择$B=O(\\epsilon^{1/2}X)$和$C = O(\\epsilon^{1/2})Y$。\n", + "\n", + "备注:虽然$A$有点小,但它的数学表达式是准确已知的。因此,$B$和$C$也是已知的。\n", + "\n", + "- 现在,让我们尝试以下方法:\n", + "$$\n", + "\\boxed{\n", + "W \\equiv e^{i B^{\\prime}} e^{i C^{\\prime}} e^{-i B^{\\prime}} e^{-i C^{\\prime}}=I-\\left[B^{\\prime}, C^{\\prime}\\right]+O\\left(\\epsilon^{3 / 2}\\right)\n", + "}\n", + "$$\n", + "其中门$e^{iB'}$是$e^{iB}$的近似值,并且类似地$e^{iC'}$是$e^{iC}$的近似值。这意味着$\\left\\|e^{i B^{\\prime}}-e^{i B}\\right\\|=O(\\epsilon),\\left\\|e^{i C^{\\prime}}-e^{i C}\\right\\|=O(\\epsilon)$,进而得到$\\|B'-B\\|=O(\\epsilon)$和$\\|C'-C\\|=O(\\epsilon)$。\n", + "\n", + "- 让我们进行验证:\n", + "$$\n", + "e^{i B^{\\prime}} e^{i C^{\\prime}} e^{-i B^{\\prime}} e^{-i C^{\\prime}}=\\left(I+i B^{\\prime}+O(\\epsilon)\\right)\\left(I+i C^{\\prime}+O(\\epsilon)\\right)\\left(I-i B^{\\prime}+O(\\epsilon)\\right)\\left(I-i C^{\\prime}+O(\\epsilon)\\right)\n", + "$$\n", + "如果你只查看一阶项,它们会被相互抵消。为什么二阶项只包含$[B', C']$?(**homework**)\n", + "\n", + "- 现在,如果我们关注对易子,我们有\n", + "$$\n", + "\\left[B^{\\prime}, C^{\\prime}\\right]=[B+O(\\epsilon), C+O(\\epsilon)]=[B, C]+O\\left(\\epsilon^{3 / 2}\\right)\n", + "$$\n", + "这意味着你可以将$[B', C']$替换为$[B, C]= -iA$。换句话说,\n", + "$$\n", + "W=I+i A+O\\left(\\epsilon^{3 / 2}\\right)=e^{i A}+O\\left(\\epsilon^{3 / 2}\\right)\n", + "$$\n", + "这完成了证明。\n", + "\n", + "---\n", + "\n", + "因此,我们现在从$\\epsilon$-net有效地构建了一个$\\epsilon^{3/2}$-net,代价是总共应用5个门,即$WV=e^{i B^{\\prime}} e^{i C^{\\prime}} e^{-i B^{\\prime}} e^{-i C^{\\prime}}V$,这来自于$\\epsilon$-net。现在,如果我们再次替换整个论点,那么我们会得到一个更好的网络(如果我们不关心额外的门):$~(\\epsilon^{3/2})^{3/2}=\\epsilon^{(3/2)^2}$。更严格地,让我们通过(上限)量化新误差\n", + "$$\n", + "\\epsilon_{1}=c \\epsilon_{0}^{3 / 2} \\quad \\text { or } \\quad c^{2} \\epsilon_{1}=\\left(c^{2} \\epsilon_{0}\\right)^{3 / 2}\n", + "$$\n", + "其中$\\epsilon_0$是 epsilon-net 中的原始值,并且$c$是某个常数。\n", + "\n", + "此外,如果需要花费(最大)$L_0$基本门在$\\epsilon$-net 中实现$V$,那么需要花费$L_1=5L_0$个门$\\{e^{i B^{\\prime}}, e^{i C^{\\prime}}, e^{-i B^{\\prime}}, e^{-i C^{\\prime}}, V\\}$来构建$\\epsilon^{3/2}$-net。如果我们更进一步,那么我们有\n", + "$$\n", + "\\epsilon_{2}=c \\epsilon_{1}^{3 / 2} \\quad \\text { or } \\quad c^{2} \\epsilon_{2}=\\left(c^{2} \\epsilon_{1}\\right)^{3 / 2}=\\left(c^{2} \\epsilon_{0}\\right)^{(3 / 2)^{2}}\n", + "$$\n", + "\n", + "下一次(第 2 级),你需要应用来自 $\\epsilon^{3/2}$-net 的集合来近似门集合如$\\{e^{i B^{\\prime}}, e^{i C^{\\prime}}, e^{-i B^{\\prime}}, e^{-i C^{\\prime}}, WV \\}$ 。那将是$5(5L_0)$个门。\n", + "\n", + "一般来说,在级别 $k$,我们有\n", + "$$\n", + "c^{2} \\epsilon_{k}=\\left(c^{2} \\epsilon_{k-1}\\right)^{3 / 2}=\\left(c^{2} \\epsilon_{0}\\right)^{(3 / 2)^{k}}\n", + "$$\n", + "我们总共需要$L_k=5L_{k-1}=5^k L_0$。\n", + "\n", + "现在,我们的情况是,如果我们愿意支付应用指数个门(以 $k$ 为单位)的成本,那么我们会在缩小误差方面获得双指数效应。因此,我们可能会获得一些优势(**homework**)\n", + "\n", + "$$\n", + "\\frac{L_{k}}{L_{0}}=5^{k}=\\left(\\frac{\\log \\left(1 / c^{2} \\epsilon_{k}\\right)}{\\log \\left(1 / c^{2} \\epsilon_{0}\\right)}\\right)^{\\log 5 / \\log (3 / 2)}\n", + "$$\n", + "\n", + "如果我们忘记了常量,那么我们有更标准的形式:\n", + "$$\n", + "L_{k}=O\\left(\\log \\left(1 / \\epsilon_{k}\\right)^{3.97}\\right)\n", + "$$\n", + "\n", + "这个表达式告诉我们,如果我们想要实现$\\epsilon_k$大小的近似值,那么您预计每个门都会有$O\\left(\\log \\left(1 / \\epsilon_{k}\\right)^{3.97}\\right)$的额外成本,这只会带来多项式开销。例如,在某个$n$量子比特的量子算法中,我们有一个 poly(n) 的电路。 将每个门改进为 $\\epsilon_k$后,我们仍然有一个多项式电路。" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/lecture19.ipynb b/lecture19.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..e48127271a663b7d5fc3dc562ed4a30a9aedc764 --- /dev/null +++ b/lecture19.ipynb @@ -0,0 +1,311 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Lecture 19\n", + "\n", + "到目前为止,我们的讨论相当笼统。适用于大多数量子算法的框架。现在,是时候研究一些“真实”量子算法的细节了,但这些算法可能并不“实用”,因为我们只是试图证明量子计算的想法。我们首先需要理清的是,量子计算机是如何进行经典计算的。在这里,重要的一点是 Toffoli 门对于经典计算机是“通用的”。想象一下,我们有一个经典电路,带有 AND、OR、NOT 等逻辑门,其想法是用 Toffoli 门(连同一些辅助位)替换每个逻辑门。\n", + "\n", + "有两个问题需要弄清楚。\n", + "\n", + "- 首先,经典计算是不可逆的(信息丢失),但量子计算是可逆的(信息守恒)。\n", + "\n", + "- 其次,一些经典计算涉及随机性。\n", + "\n", + "这两个问题都可以通过量子计算来克服,方法是保留信息并使用量子测量,例如在$|+\\rangle$态上测量。\n", + "\n", + "## Toffoli 门\n", + "\n", + "让我们看一下toffoli门的逻辑表。\n", + "\n", + "![Toffoli gate logic table](images/Toffoli_logic_table.png)\n", + "\n", + "【事实】与非门(NAND 门)(与门 后接 非门)对于经典计算是通用的。这足以证明如果Toffoli 门可以模拟与非门,那么Toffoli 门对于经典计算也是通用的。\n", + "\n", + "![NAND gate](images/NAND_gate.png)\n", + "\n", + "为了检查,让我们看一下 NAND 逻辑表:\n", + "\n", + "![NAND logic table](images/NAND_logic_table.png)\n", + "\n", + "由于 Toffoli 门可以使用基本量子门构建,因此经典计算可以被量子计算机实现。需要注意的是,量子计算机执行经典计算将会产生额外的开销。\n", + "\n", + "一个很好的类比:量子计算机确实可以模拟经典计算,但量子计算机不太可能取代经典计算机。为什么?就像飞机都可以像汽车一样操作,但我们不会用飞机代替汽车。\n", + "\n", + "## 量子并行\n", + "\n", + "当我还是一名研究生时,我是团队中唯一从事量子计算的人。在一次组会上,我试图解释量子计算,然后我写了这个($x \\in \\{ 0,1 \\}^n$):\n", + "$$\n", + "\\boxed{\n", + "|x\\rangle |0\\rangle \\rightarrow |x\\rangle |f(x)\\rangle\n", + "}\n", + "$$\n", + "\n", + "组里的其他人对此很满意,但是当我以叠加的形式写出来时:\n", + "$$\n", + "\\boxed{\n", + "\\sum_x |x\\rangle |0\\rangle \\rightarrow \\sum_x |x\\rangle |f(x)\\rangle\n", + "}\n", + "$$\n", + "他们不相信这是真的。\n", + "\n", + "或许我应该评论一下:量子计算机可以做这样的事情吗?$|x\\rangle \\rightarrow |f(x)\\rangle$ 但这通常是不可逆的。\n", + "\n", + "实际上,我们需要的是一些辅助量子比特。因此,我们实际上需要执行以下操作:\n", + "$$\n", + "|x\\rangle|0\\rangle|0\\rangle_{a n c} \\rightarrow|x\\rangle|f(x)\\rangle|g(x)\\rangle_{a n c} \\rightarrow|x\\rangle|f(x)\\rangle\n", + "$$\n", + "这仍然是一个简化版本。可能最好的方法是通过一些明确的例子来说明。例如,如果要执行的逻辑操作恰好是与非门。\n", + "\n", + "- 单一状态:\n", + "$$\n", + "|ab\\rangle |1\\rangle \\rightarrow |ab\\rangle |1+ab\\rangle\n", + "$$\n", + "\n", + "- 叠加:\n", + "$$\n", + "(|00\\rangle+|01\\rangle+|10\\rangle+|11\\rangle)|1\\rangle \\rightarrow|00\\rangle|1\\rangle+|01\\rangle|1\\rangle+|10\\rangle|1\\rangle+|11\\rangle|0\\rangle\n", + "$$" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "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\nH\n \n\n\n\n\nX\n \n\n\n\n\n\n\nX\n \n\n
", + "text/plain": [ + "" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from mindquantum.core.circuit import Circuit\n", + "from mindquantum.core.gates import X, H\n", + "\n", + "circ = Circuit()\n", + "circ += H.on(0)\n", + "circ += H.on(1)\n", + "circ += X.on(2)\n", + "circ += X.on(2, [1, 0])\n", + "circ.svg()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "$q_0$、$q_1$是输入比特,$q_2$是输出比特。现在按照$|q_0 q_1 q_2\\rangle$的顺序打印量子态,即得到叠加情况下的$|ab\\rangle |1+ab\\rangle$:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1/2¦001⟩\n", + "1/2¦011⟩\n", + "1/2¦101⟩\n", + "1/2¦110⟩\n" + ] + } + ], + "source": [ + "print(circ.reverse_qubits().get_qs(ket=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "现在,想象一下,如果我们需要进一步处理输出的量子比特,\n", + "$$\n", + "|a b\\rangle|1\\rangle \\rightarrow|a b\\rangle|1+a b\\rangle|1\\rangle \\rightarrow|a b\\rangle \\enspace |1+a b\\rangle \\enspace |1+a(1+a b)\\rangle\n", + "$$" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "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\nX\n \n\n\n\n\n\n\nX\n \n\n\n\n\nX\n \n\n\n\n\n\n\nX\n \n\n
", + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "circ += X.on(3)\n", + "circ += X.on(3, [0, 2])\n", + "circ.svg()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "现在$q_0$、$q_1$是输入比特,$q_2$是辅助比特,$q_3$是输出比特。但这样中间部分会出现叠加问题:\n", + "$$\n", + "\\begin{array}{c}\n", + "(|00\\rangle|1\\rangle+|01\\rangle|1\\rangle+|10\\rangle|1\\rangle+|11\\rangle|0\\rangle)|1\\rangle \\\\ \\\\\n", + "\\rightarrow|00\\rangle|1\\rangle|1\\rangle+|01\\rangle|1\\rangle|1\\rangle+|10\\rangle|1\\rangle|0\\rangle+|11\\rangle|0\\rangle|1\\rangle \\\\ \\\\\n", + "|00\\rangle|g(00)\\rangle_{a n c}|f(00)\\rangle+|01\\rangle|g(01)\\rangle_{a n c}|f(01)\\rangle+|10\\rangle|g(10)\\rangle_{a n c}|f(10)\\rangle+|11\\rangle|g(11)\\rangle_{a n c}|f(11)\\rangle\n", + "\\end{array}\n", + "$$\n", + "这里的函数$f$就是我们想要应用的逻辑操作,即应用两个与非门,但是辅助量子比特$q_2$会与输入量子比特$q_0$、$q_1$纠缠在一起,如下所示。" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1/2¦0011⟩\n", + "1/2¦0111⟩\n", + "1/2¦1010⟩\n", + "1/2¦1101⟩\n" + ] + } + ], + "source": [ + "print(circ.reverse_qubits().get_qs(ket=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "要摆脱它,我们可以再次应用 Toffoli 门。" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "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\nX\n \n\n\n\n\n\n\nX\n \n\n\n\n\nX\n \n\n\n\n\n\n\nX\n \n\n\n\n\n\n\nX\n \n\n
", + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "circ += X.on(2, [0, 1])\n", + "circ.svg()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1/2¦0011⟩\n", + "1/2¦0111⟩\n", + "1/2¦1010⟩\n", + "1/2¦1111⟩\n" + ] + } + ], + "source": [ + "print(circ.reverse_qubits().get_qs(ket=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "可以看到,辅助比特$q_2$现在恢复了初始状态。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 量子叠加\n", + "\n", + "对于一个单量子比特,我们知道\n", + "$$\n", + "H|0\\rangle = (|0\\rangle+|1\\rangle)/\\sqrt{2}\n", + "$$\n", + "\n", + "对于两个量子比特:\n", + "$$\n", + "H^{\\otimes 2}|00\\rangle=(|0\\rangle+|1\\rangle)(|0\\rangle+|1\\rangle) / 2=(|00\\rangle+|01\\rangle+|10\\rangle+|11\\rangle) / 2\n", + "$$\n", + "\n", + "对于多量子比特,\n", + "$$\n", + "H^{\\otimes n}\\left|0^{n}\\right\\rangle=\\frac{1}{\\sqrt{2^{n}}} \\sum_{x \\in\\{0,1\\}^{n}}|x\\rangle\n", + "$$\n", + "\n", + "在$n$个量子比特上使用$n$个 Hadmard 门,可以创建具有 $2^n$ 输入项的量子叠加。指数希尔伯特空间是使其成为经典模拟难题的必要条件(但不是充分条件)。\n", + "\n", + "结合前面的讨论,我们可以断言存在一个幺正的电路$U_f$,这样\n", + "$$\n", + "\\boxed{\n", + "\\sum_{x} a_{x} U_{f}|x\\rangle|0\\rangle=\\sum_{x} a_{x}|x\\rangle|f(x)\\rangle\n", + "}\n", + "$$\n", + "其中$f(x)$是一些可以表示为经典电路的函数。" + ] + } + ], + "metadata": { + "interpreter": { + "hash": "01ef07bfcd890b3fb13769b93b40ebec23f083c4455175924b1f47ada90ba335" + }, + "kernelspec": { + "display_name": "Python 3.8.13 ('mq')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.13" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/lecture20.ipynb b/lecture20.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..5210a2783e715d8a31841a705466cbbde76acd57 --- /dev/null +++ b/lecture20.ipynb @@ -0,0 +1,246 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Lecture 20\n", + "\n", + "## Deutsch 算法(基于oracle的算法)\n", + "\n", + "我们应该首先了解 oracle 的概念,可以被认为是一个黑盒子,例如有人设计了一个经典电路,而没有向你解释它是什么,并且你不被允许查看它。\n", + "\n", + "出于实际目的,我们仅指经典计算部分,\n", + "$$\n", + "\\boxed{\n", + "|x\\rangle|0\\rangle \\rightarrow|x\\rangle|f(x)\\rangle\n", + "}\n", + "$$\n", + "我们不在乎$f(x)$是如何构造的。\n", + "\n", + "此外,我们还可以进行以下操作(针对布尔函数)\n", + "$$\n", + "\\boxed{\n", + "|x\\rangle \\rightarrow (-1)^{f(x)}|x\\rangle\n", + "}\n", + "$$\n", + "我们可以通过以下方式实现(有时称为相位反冲)(在叠加状态中添加额外的辅助量子比特):\n", + "$$\n", + "U_{\\mathrm{CNOT}}|f(x)\\rangle(|0\\rangle-|1\\rangle)=|f(x)\\rangle(|0 \\oplus f(x)\\rangle-|1 \\oplus f(x)\\rangle)=(-1)^{f(x)}|f(x)\\rangle(|0\\rangle-|1\\rangle)\n", + "$$\n", + "换句话说,我们必须应用序列(忽略一些辅助量子比特):\n", + "$$\n", + "|x\\rangle \\rightarrow|x\\rangle|f(x)\\rangle \\rightarrow(-1)^{f(x)}|x\\rangle|f(x)\\rangle \\rightarrow(-1)^{f(x)}|x\\rangle\n", + "$$\n", + "Deutsch 算法解决了以下问题:给定一个 oracle 布尔函数$f(x)$,它将一比特作为输入,一比特作为输出。有两种可能性:constant或balanced,\n", + "\n", + "– 情况 1(constant):$f(0) = f(1)$\n", + "\n", + "* 两种可能,$f(0)=f(1)=0$或$f(0)=f(1)=1$\n", + "\n", + "– 情况 2(balanced):$f(0) \\ne f(1)$\n", + "\n", + "* 两种可能,$\\{f(0)=1,f(1)=0\\}$或$\\{f(0)=0,f(1)=1\\}$\n", + "\n", + "传统上,必须对函数进行两次评估。如果你只调用一次oracle,你只能知道$f(0)$或$f(1)$,但不能同时知道两者。而 Deutsch 算法允许我们通过只调用一次oracle来解决问题(确定它是情况 1 还是情况 2)。\n", + "\n", + "**步骤1:**\n", + "\n", + "让我们首先创建输入的叠加,即\n", + "$$\n", + "H|0\\rangle = \\frac{1}{\\sqrt{2}}(|0\\rangle+|1\\rangle)\n", + "$$\n", + "\n", + "**步骤2:**\n", + "\n", + "我们应用oracle:\n", + "$$\n", + "\\frac{1}{\\sqrt{2}}\\left((-1)^{f(0)}|0\\rangle+(-1)^{f(1)}|1\\rangle\\right)\n", + "$$\n", + "请注意,如果是情况 1,那么这只是$|+\\rangle$(差一个正负号); 如果是情况 2,那么我们有$|-\\rangle$(差一个正负号)。\n", + "\n", + "**步骤3:**\n", + "\n", + "最后,我们只需要区分$|+\\rangle$或$|-\\rangle$态,可以通过作用 Hadamard 门来实现:$H|+\\rangle=|0\\rangle$,$H|-\\rangle=|1\\rangle$\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "X\n", + "q0: ──H─────────●────H───────────\n", + " │\n", + "q1: ──X────H────X────H────M(q1)──\n" + ] + }, + { + "data": { + "text/html": [ + "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "
shots: 100\n",
+       "Keys: q1│0.00     0.2         0.4         0.6         0.8         1.0\n",
+       "────────┼───────────┴───────────┴───────────┴───────────┴───────────┴\n",
+       "       1│▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓\n",
+       "\n",
+       "{'1': 100}\n",
+       "
\n" + ], + "text/plain": [ + "shots: 100\n", + "Keys: q1│0.00 0.2 0.4 0.6 0.8 1.0\n", + "────────┼───────────┴───────────┴───────────┴───────────┴───────────┴\n", + " 1│▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓\n", + " │\n", + "{'1': 100}" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from mindquantum import H, Simulator, Circuit, UnivMathGate, IGate, Measure, X, I\n", + "import numpy as np\n", + "\n", + "\n", + "# const = UnivMathGate('const', np.array([[1, 0], [0, 0]]))\n", + "const = X\n", + "balanced = IGate()\n", + "\n", + "rnd = np.random.rand()\n", + "if rnd < 0.5:\n", + " f = const\n", + "else:\n", + " f = balanced\n", + "\n", + "\n", + "print(f)\n", + "circ = Circuit()\n", + "circ += X.on(1)\n", + "circ += H.on(0)\n", + "circ += H.on(1)\n", + "\n", + "circ += f.on(1, 0)\n", + "circ += H.on(0)\n", + "circ += H.on(1)\n", + "circ += Measure().on(1)\n", + "\n", + "print(circ)\n", + "sim = Simulator('projectq', circ.n_qubits)\n", + "res = sim.sampling(circ, shots=100)\n", + "res" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Deutsch-Jozsa 算法\n", + "\n", + "![Deutsch Jozsa algorithm](images/Deutsch_Jozsa_algorithm.png)\n", + "\n", + "后来,Jozsa 与 Deutsch 合作,将原始算法扩展到多个量子比特案例。\n", + "\n", + "Deutsch-Jozsa 算法求解的问题如下:\n", + "\n", + "- 给定一个 n 比特布尔函数的oracle,$f(x)\\rightarrow \\{0,1\\}$,对于任意$x \\in \\{0,1\\}^n$\n", + "\n", + "- (promised problem)确定两种情况:constant 或 balanced\n", + "\n", + "* **constant:**对于所有的$x$都有$f(x)=0$或$f(x)=1$\n", + "\n", + "* **balanced:**($f(x)=0$的数量)=($f(x)=1$的数量)\n", + "\n", + "现在这是一个更加人造的问题。\n", + "\n", + "示例:对于两比特情况:\n", + "\n", + "– **constant:**$f(00)=f(01)=f(10)=f(11)=0$\n", + "\n", + "– **balanced:**$f(00)=f(01)=0$和$f(10)=f(11)=1$\n", + "\n", + "让我们考虑解决问题的经典方法。从计算机科学的角度来看,我们经常对算法在最坏情况下的性能感兴趣;如果你尝试不到$2^n$的一半的组合,你仍然不能确定这个函数是constant还是balanced。因此,对于这个问题,经典的最坏情况需要我们尝试超过$2^{n-1}$种组合。\n", + "\n", + "现在让我们考虑量子算法:\n", + "\n", + "**步骤1:**\n", + "\n", + "• 我们同样创建一个量子叠加:\n", + "$$\n", + "H^{\\otimes n}\\left|0^{n}\\right\\rangle=\\frac{1}{\\sqrt{2^{n}}} \\sum_{x \\in\\{0,1\\}^{n}}|x\\rangle\n", + "$$\n", + "\n", + "**步骤2:**\n", + "\n", + "我们应用同样的技巧将布尔函数的结果编码为符号,即,\n", + "$$\n", + "\\frac{1}{\\sqrt{2^{n}}} \\sum_{x \\in\\{0,1\\}^{n}} U_{f}|x\\rangle=\\frac{1}{\\sqrt{2^{n}}} \\sum_{x \\in\\{0,1\\}^{n}}(-1)^{f(x)}|x\\rangle\n", + "$$\n", + "如果它是constant,那么我们在第一步中就有原始状态。如果它是 balanced 的,那么我们的东西会更复杂,但我们可以让它变得简单。\n", + "\n", + "**步骤3:**\n", + "\n", + "回想一下$H|0\\rangle=(|0\\rangle+|1\\rangle)/\\sqrt{2}$和$H|1\\rangle=(|0\\rangle-|1\\rangle)/\\sqrt{2}$,其中减号只能在$|1\\rangle$态前。\n", + "$$\n", + "\\frac{1}{\\sqrt{2^{n}}} \\sum_{x \\in\\{0,1\\}^{n}}(-1)^{f(x)} H^{\\otimes n}|x\\rangle=\\frac{1}{2^{n}}\\left(\\sum_{x \\in\\{0,1\\}^{n}}(-1)^{f(x)}\\right)|000 \\ldots 0\\rangle+\\ldots\n", + "$$\n", + "此处未显示的部分在基向量中至少包含一个“1”。例如:$H^{\\otimes 2}|01\\rangle=(|0\\rangle+|1\\rangle)(|0\\rangle-|1\\rangle) / 2=(1 / 2)|00\\rangle+\\ldots$\n", + "\n", + "现在,我们可以很清楚地看到, constant 的幅度为 1,而 balanced 的幅度为 0。总之,我们可以通过应用一次oracle来解决问题,并检查最终输出是否在$|000\\ldots 0\\rangle$。\n", + "\n", + "## 作业\n", + "\n", + "请在 MindQuanutum 中实现三比特的 Deutsch-Jozsa 算法。" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "interpreter": { + "hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49" + }, + "kernelspec": { + "display_name": "Python 3.9.9 64-bit", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.13" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/lecture21.ipynb b/lecture21.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..efaa87b2816a2af79d8bb5213ae8990a80b27a41 --- /dev/null +++ b/lecture21.ipynb @@ -0,0 +1,201 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Lecture 21\n", + "\n", + "## 量子模拟\n", + "\n", + "当我还是学生的时候,“量子模拟”这个词是指使用经典计算机来解决量子问题,例如动力学或基态等。我现在想,这个词现在意味着用量子设备解决量子问题。我们感兴趣的是研究模拟一些“局部”哈密顿函数的量子酉运算问题。\n", + "\n", + "让我们回忆一下薛定谔方程($\\hbar = 1$):\n", + "$$\n", + "i \\frac{d}{d t}|\\psi(t)\\rangle=H|\\psi(t)\\rangle\n", + "$$\n", + "其中$H$被假定为时间无关的哈密顿量。\n", + "\n", + "你只需要知道,可以将上述等式改写如下:\n", + "$$\n", + "|\\psi(t)\\rangle=e^{-i H t}|\\psi(t=0)\\rangle\n", + "$$\n", + "\n", + "我们的量子模拟目标是使用一组(基本)量子门(假设初始状态很容易准备或给定)来准备时间相关状态$|\\psi(t)\\rangle$。\n", + "\n", + "### 定义误差\n", + "\n", + "给定一个运算符(矩阵)$X$,考虑另一个运算符$Y\\equiv X+\\Delta_x$。我们写为\n", + "$$\n", + "X+O(\\epsilon) \\leftrightarrow\\left\\|\\Delta_{X}\\right\\|=O(\\epsilon)\n", + "$$\n", + "这里没有指定矩阵范数。\n", + "\n", + "回忆一下指数算子的定义,\n", + "$$\n", + "e^{-i H t}=I-i H t+\\sum_{m=2}^{\\infty} \\frac{(-i H t)^{m}}{m !}\n", + "$$\n", + "\n", + "回想一下,算子范数满足以下三角不等式:\n", + "$$\n", + "\\|X+Y\\| \\leq\\|X\\|+\\|Y\\|\n", + "$$\n", + "\n", + "因此,我们可以对算子进行绑定:\n", + "$$\n", + "\\left\\|\\sum_{m=2}^{\\infty} \\frac{(-i H t)^{m}}{m !}\\right\\| \\leq(\\|H\\| t)^{2} \\sum_{m=0}^{\\infty} \\frac{(\\|H\\| t)^{m}}{(m+2) !}\n", + "$$\n", + "\n", + "假设我们限制演化时间,这样\n", + "$$\n", + "\\left\\|H\\right\\|t=1\n", + "$$\n", + "\n", + "最后一项可以被限制为\n", + "$$\n", + "\\sum_{m=0}^{\\infty} \\frac{(\\|H\\| t)^{m}}{(m+2) !} \\leq \\sum_{m=0}^{\\infty} \\frac{1}{(m+2) !}=e-1-1<1\n", + "$$\n", + "这是因为我们可以考虑$e^x=1+x+\\sum^\\infty_{m=2}\\frac{x^m}{m !}$,并且因此$e=1+1+\\sum^\\infty_{m=0}\\frac{1}{(m+1) !}$。\n", + "\n", + "作为结果,我们得到\n", + "$$\n", + "\\boxed{\n", + "e^{-i H t}=I-i H t+O\\left(\\|H\\|^{2} t^{2}\\right)\n", + "}\n", + "$$\n", + "\n", + "### k-local 哈密顿量\n", + "\n", + "让我们考虑一个包含 $n$ 个自旋 1/2 粒子(量子比特)的系统,总哈密顿量是自旋之间相互作用的总和,即,\n", + "$$\n", + "H=\\sum^L_{j=1}H_j\n", + "$$\n", + "其中$H_j$只作用于最多 $k < n$ 个自旋。\n", + "\n", + "重要的一点是你可以改变 $n$,但保持 $k$ 固定。在这里,我们更多地考虑数学,因此没有强加物理局部性,即$k$-local 并不意味着空间中的局部。一个需要解决的技术问题是,我们需要确保$L$不能是指数的。例如,哈密顿量的项恰好包含 $k$ 体相互作用,则\n", + "$$\n", + "L \\le C^n_k=O(n^k)=poly(n)\n", + "$$\n", + "\n", + "### 对易情形\n", + "\n", + "作为一种特殊情况,考虑所有项相互对易的情况,即 $[H_j,H_i]=0$。这是有可能发生的,例如伊辛模型: $H=\\sum J_{ij} Z_i Z_j$。\n", + "\n", + "在这种情况下,我们可以像这样分离每一项:\n", + "$$\n", + "\\le e^{-i H t}=e^{-i H_{1} t} e^{-i H_{2} t} \\cdots e^{-i H_{L} t}\n", + "$$\n", + "\n", + "为确保最终误差在 $\\epsilon$ 范围内,可以通过要求每个算子有一个以 $\\epsilon / L$ 为范围的误差来实现这一点。\n", + "\n", + "如果我们考虑使用$H$门和$T$门模拟每个基本门,那么根据Solavay-Kitaev 定理,我们需要$O(log^c(L/\\epsilon))$个门。因为我们有 $L$ 个这样的项,所以我们需要考虑用$O\\left(L\\enspace log^c \\left(L/ \\epsilon\\right)\\right)$个门。\n", + "\n", + "### 不对易情形\n", + "\n", + "在 $[H_j,H_i]\\ne 0$ 的情况下,我们的展开形式不再起作用,即\n", + "$$\n", + "e^{-i H t} \\neq e^{-i H_{1} t} e^{-i H_{2} t} \\cdots e^{-i H_{L} t}\n", + "$$\n", + "\n", + "当然,当 $t$ 很小时(让我们用 $\\Delta t$ 代替),我们可以近似地使\n", + "$$\n", + "e^{-i H \\Delta t} \\approx e^{-i H_{1} \\Delta t} e^{-i H_{2} \\Delta t} \\cdots e^{-i H_{L} \\Delta t}\n", + "$$\n", + "但我们想让这个近似值尽可能严格。\n", + "\n", + "首先,我们确实有一个等式如下:\n", + "$$\n", + "e^{-i H t}=\\lim _{n \\rightarrow \\infty}\\left(e^{-i H_{1} t / n} e^{-i H_{2} t / n} \\cdots e^{-i H_{L} t / n}\\right)^{n}\n", + "$$\n", + "\n", + "但是这个等式并不那么实用,因为它需要$n \\rightarrow \\infty$。而我们对有限数量的项更感兴趣。\n", + "\n", + "---\n", + "\n", + "**Lie-Trotter 乘积公式**\n", + "\n", + "对于一对 Hermitian 算子 $A$ 和 $B$ ,其中 $\\left\\| A \\right\\| < s < 1$ 和 $\\left\\| B \\right\\| < s < 1$ ,我们有\n", + "$$\n", + "\\boxed{\n", + "e^{-i A} e^{-i B}=e^{-i(A+B)}+O\\left(s^{2}\\right)\n", + "}\n", + "$$\n", + "\n", + "**证明:**\n", + "\n", + "首先, $e^{-iA}=I-iA+O(s^2)$ 和 $e^{-iB}=I-iB+O(s^2)$ ,现在我们可以同时展开它们:\n", + "$$\n", + "e^{-i A} e^{-i B}=\\left(I-i A+O\\left(s^{2}\\right)\\right)\\left(I-i B+O\\left(s^{2}\\right)\\right)=I-i(A+B)+O\\left(s^{2}\\right)\n", + "$$\n", + "\n", + "另一方面,我们可能还需要假设:$\\left\\|A+B\\right\\| < \\left\\|A\\right\\|+\\left\\|B\\right\\|<2s<1$,即可得到\n", + "$$\n", + "e^{-i(A+B)}=I-i(A+B)+O\\left(\\left\\|(A+B)^{2}\\right\\|\\right)\n", + "$$\n", + "其中$O\\left( \\left\\|(A+B)^2\\right\\| \\right)=O\\left( s^2 \\right)$。\n", + "\n", + "---\n", + "\n", + "现在,要将 Lie-Trotter 乘积公式应用于模拟问题,我们需要作出以下限制(假设对于每个项,我们有 $\\left\\|H_i\\right\\| \\Delta t