{ "cells": [ { "cell_type": "markdown", "id": "be565231", "metadata": {}, "source": [ "# 电路基础" ] }, { "cell_type": "markdown", "id": "fcdfed33", "metadata": {}, "source": [ "## 概述\n", "\n", "在这篇笔记中,我们将了解 TensorCircuit 中核心对象的基本操作-``tc.Circuit``,它支持无噪声仿真和基于蒙特卡洛轨迹的噪声仿真。更重要的是,几乎所有对 Circuit 对象的操作都是可微分的和可即时编译的,这是成功高效地进行变分量子算法模拟的关键。\n", "[WIP note]" ] }, { "cell_type": "markdown", "id": "c51c024b", "metadata": {}, "source": [ "## 设置" ] }, { "cell_type": "code", "execution_count": 1, "id": "98f21e9b", "metadata": {}, "outputs": [], "source": [ "from functools import partial\n", "import inspect\n", "import sys\n", "import numpy as np\n", "import tensorflow as tf\n", "\n", "import tensorcircuit as tc" ] }, { "cell_type": "markdown", "id": "558cdc17", "metadata": {}, "source": [ "## “Hello World\" 样例" ] }, { "cell_type": "code", "execution_count": 2, "id": "b83f24f4", "metadata": {}, "outputs": [], "source": [ "def get_circuit(n):\n", " c = tc.Circuit(n) # 用 n 个量子比特初始化一个电路对象\n", " for i in range(n):\n", " c.H(i) # 在每个量子比特上使用 Hadamard 门\n", " c.cnot(0, 1) # 在第 0 个量子比特上应用带有控制量子比特的 cnot 门\n", " c.CNOT(n - 1, n - 2) # 大写的 API 也可以正常使用\n", " return c" ] }, { "cell_type": "code", "execution_count": 3, "id": "601a072c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['i', 'x', 'y', 'z', 'h', 't', 's', 'td', 'sd', 'wroot', 'cnot', 'cz', 'swap', 'cy', 'iswap', 'ox', 'oy', 'oz', 'toffoli', 'fredkin']\n" ] } ], "source": [ "# 打印不含参数的有可能的门\n", "print(tc.Circuit.sgates)" ] }, { "cell_type": "code", "execution_count": 4, "id": "c191ea53", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "i\n", "[[1.+0.j 0.+0.j]\n", " [0.+0.j 1.+0.j]]\n", "x\n", "[[0.+0.j 1.+0.j]\n", " [1.+0.j 0.+0.j]]\n", "y\n", "[[0.+0.j 0.-1.j]\n", " [0.+1.j 0.+0.j]]\n", "z\n", "[[ 1.+0.j 0.+0.j]\n", " [ 0.+0.j -1.+0.j]]\n", "h\n", "[[ 0.70710677+0.j 0.70710677+0.j]\n", " [ 0.70710677+0.j -0.70710677+0.j]]\n", "t\n", "[[1. +0.j 0. +0.j ]\n", " [0. +0.j 0.70710677+0.70710677j]]\n", "s\n", "[[1.+0.j 0.+0.j]\n", " [0.+0.j 0.+1.j]]\n", "td\n", "[[1. +0.j 0. +0.j ]\n", " [0. +0.j 0.70710677-0.70710677j]]\n", "sd\n", "[[1.+0.j 0.+0.j]\n", " [0.+0.j 0.-1.j]]\n", "wroot\n", "[[ 0.70710677+0.j -0.5 -0.5j]\n", " [ 0.5 -0.5j 0.70710677+0.j ]]\n", "cnot\n", "[[1.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", " [0.+0.j 1.+0.j 0.+0.j 0.+0.j]\n", " [0.+0.j 0.+0.j 0.+0.j 1.+0.j]\n", " [0.+0.j 0.+0.j 1.+0.j 0.+0.j]]\n", "cz\n", "[[ 1.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", " [ 0.+0.j 1.+0.j 0.+0.j 0.+0.j]\n", " [ 0.+0.j 0.+0.j 1.+0.j 0.+0.j]\n", " [ 0.+0.j 0.+0.j 0.+0.j -1.+0.j]]\n", "swap\n", "[[1.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", " [0.+0.j 0.+0.j 1.+0.j 0.+0.j]\n", " [0.+0.j 1.+0.j 0.+0.j 0.+0.j]\n", " [0.+0.j 0.+0.j 0.+0.j 1.+0.j]]\n", "cy\n", "[[1.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", " [0.+0.j 1.+0.j 0.+0.j 0.+0.j]\n", " [0.+0.j 0.+0.j 0.+0.j 0.-1.j]\n", " [0.+0.j 0.+0.j 0.+1.j 0.+0.j]]\n", "iswap\n", "[[1.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", " [0.+0.j 0.+0.j 0.+1.j 0.+0.j]\n", " [0.+0.j 0.+1.j 0.+0.j 0.+0.j]\n", " [0.+0.j 0.+0.j 0.+0.j 1.+0.j]]\n", "ox\n", "[[0.+0.j 1.+0.j 0.+0.j 0.+0.j]\n", " [1.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", " [0.+0.j 0.+0.j 1.+0.j 0.+0.j]\n", " [0.+0.j 0.+0.j 0.+0.j 1.+0.j]]\n", "oy\n", "[[0.+0.j 0.-1.j 0.+0.j 0.+0.j]\n", " [0.+1.j 0.+0.j 0.+0.j 0.+0.j]\n", " [0.+0.j 0.+0.j 1.+0.j 0.+0.j]\n", " [0.+0.j 0.+0.j 0.+0.j 1.+0.j]]\n", "oz\n", "[[ 1.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", " [ 0.+0.j -1.+0.j 0.+0.j 0.+0.j]\n", " [ 0.+0.j 0.+0.j 1.+0.j 0.+0.j]\n", " [ 0.+0.j 0.+0.j 0.+0.j 1.+0.j]]\n", "toffoli\n", "[[1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", " [0.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", " [0.+0.j 0.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", " [0.+0.j 0.+0.j 0.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", " [0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", " [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j 0.+0.j 0.+0.j]\n", " [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j]\n", " [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j 0.+0.j]]\n", "fredkin\n", "[[1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", " [0.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", " [0.+0.j 0.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", " [0.+0.j 0.+0.j 0.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", " [0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", " [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j 0.+0.j]\n", " [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j 0.+0.j 0.+0.j]\n", " [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j]]\n" ] } ], "source": [ "# 这些门定义的相应矩阵\n", "for g in tc.Circuit.sgates:\n", " gf = getattr(tc.gates, g)\n", " print(g)\n", " print(tc.gates.matrix_for_gate(gf()))" ] }, { "cell_type": "code", "execution_count": 5, "id": "96c15225", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[{'gatef': h,\n", " 'gate': Gate(\n", " name: 'h',\n", " tensor:\n", " array([[ 0.70710677+0.j, 0.70710677+0.j],\n", " [ 0.70710677+0.j, -0.70710677+0.j]], dtype=complex64),\n", " edges: [\n", " Edge('cnot'[2] -> 'h'[0] ),\n", " Edge('h'[1] -> 'qb-1'[0] )\n", " ]),\n", " 'index': (0,),\n", " 'name': 'h',\n", " 'split': None,\n", " 'mpo': False},\n", " {'gatef': h,\n", " 'gate': Gate(\n", " name: 'h',\n", " tensor:\n", " array([[ 0.70710677+0.j, 0.70710677+0.j],\n", " [ 0.70710677+0.j, -0.70710677+0.j]], dtype=complex64),\n", " edges: [\n", " Edge('cnot'[3] -> 'h'[0] ),\n", " Edge('h'[1] -> 'qb-2'[0] )\n", " ]),\n", " 'index': (1,),\n", " 'name': 'h',\n", " 'split': None,\n", " 'mpo': False},\n", " {'gatef': h,\n", " 'gate': Gate(\n", " name: 'h',\n", " tensor:\n", " array([[ 0.70710677+0.j, 0.70710677+0.j],\n", " [ 0.70710677+0.j, -0.70710677+0.j]], dtype=complex64),\n", " edges: [\n", " Edge('cnot'[2] -> 'h'[0] ),\n", " Edge('h'[1] -> 'qb-3'[0] )\n", " ]),\n", " 'index': (2,),\n", " 'name': 'h',\n", " 'split': None,\n", " 'mpo': False},\n", " {'gatef': cnot,\n", " 'gate': Gate(\n", " name: 'cnot',\n", " tensor:\n", " array([[[[1.+0.j, 0.+0.j],\n", " [0.+0.j, 0.+0.j]],\n", " \n", " [[0.+0.j, 1.+0.j],\n", " [0.+0.j, 0.+0.j]]],\n", " \n", " \n", " [[[0.+0.j, 0.+0.j],\n", " [0.+0.j, 1.+0.j]],\n", " \n", " [[0.+0.j, 0.+0.j],\n", " [1.+0.j, 0.+0.j]]]], dtype=complex64),\n", " edges: [\n", " Edge(Dangling Edge)[0],\n", " Edge('cnot'[3] -> 'cnot'[1] ),\n", " Edge('cnot'[2] -> 'h'[0] ),\n", " Edge('cnot'[3] -> 'h'[0] )\n", " ]),\n", " 'index': (0, 1),\n", " 'name': 'cnot',\n", " 'split': None,\n", " 'mpo': False},\n", " {'gatef': cnot,\n", " 'gate': Gate(\n", " name: 'cnot',\n", " tensor:\n", " array([[[[1.+0.j, 0.+0.j],\n", " [0.+0.j, 0.+0.j]],\n", " \n", " [[0.+0.j, 1.+0.j],\n", " [0.+0.j, 0.+0.j]]],\n", " \n", " \n", " [[[0.+0.j, 0.+0.j],\n", " [0.+0.j, 1.+0.j]],\n", " \n", " [[0.+0.j, 0.+0.j],\n", " [1.+0.j, 0.+0.j]]]], dtype=complex64),\n", " edges: [\n", " Edge(Dangling Edge)[0],\n", " Edge(Dangling Edge)[1],\n", " Edge('cnot'[2] -> 'h'[0] ),\n", " Edge('cnot'[3] -> 'cnot'[1] )\n", " ]),\n", " 'index': (2, 1),\n", " 'name': 'cnot',\n", " 'split': None,\n", " 'mpo': False}]" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c = get_circuit(3)\n", "ir = c.to_qir() # 电路的中间表示\n", "ir" ] }, { "cell_type": "code", "execution_count": 6, "id": "9ab7fd6e", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(array([[ 0.70710677+0.j, 0.70710677+0.j],\n", " [ 0.70710677+0.j, -0.70710677+0.j]], dtype=complex64),\n", " array([[[[1.+0.j, 0.+0.j],\n", " [0.+0.j, 0.+0.j]],\n", " \n", " [[0.+0.j, 1.+0.j],\n", " [0.+0.j, 0.+0.j]]],\n", " \n", " \n", " [[[0.+0.j, 0.+0.j],\n", " [0.+0.j, 1.+0.j]],\n", " \n", " [[0.+0.j, 0.+0.j],\n", " [1.+0.j, 0.+0.j]]]], dtype=complex64))" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ir[0][\"gatef\"]().tensor, ir[-1][\"gate\"].tensor # 每个门的实际幺正矩阵" ] }, { "cell_type": "code", "execution_count": 7, "id": "ecdc0f1a", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0.35355335+0.j, 0.35355335+0.j, 0.35355335+0.j, 0.35355335+0.j,\n", " 0.35355335+0.j, 0.35355335+0.j, 0.35355335+0.j, 0.35355335+0.j],\n", " dtype=complex64)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 计算电路的最终输出量子态\n", "c.state()" ] }, { "cell_type": "code", "execution_count": 8, "id": "64fa321b", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(0.9999998+0j) 0j\n" ] } ], "source": [ "# 计算一些期望值,比如 <X1>\n", "x1 = c.expectation([tc.gates.x(), [1]])\n", "\n", "# 或 <Z1Z2>\n", "z1z2 = c.expectation([tc.gates.z(), [1]], [tc.gates.z(), [2]])\n", "\n", "print(x1, z1z2)" ] }, { "cell_type": "code", "execution_count": 9, "id": "c8292569", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(array([1., 1., 1.], dtype=float32), 0.1250001713634208)\n", "(array([0., 0., 1.], dtype=float32), 0.12499997764825821)\n", "(array([0., 1., 1.], dtype=float32), 0.12499997764825821)\n", "(array([1., 1., 0.], dtype=float32), 0.1249999776482098)\n", "(array([1., 1., 0.], dtype=float32), 0.1249999776482098)\n", "(array([1., 0., 1.], dtype=float32), 0.12499997019766829)\n", "(array([0., 1., 0.], dtype=float32), 0.12499997764825821)\n", "(array([1., 1., 0.], dtype=float32), 0.1249999776482098)\n", "(array([0., 0., 0.], dtype=float32), 0.12499997764825821)\n", "(array([0., 1., 1.], dtype=float32), 0.12499997764825821)\n" ] } ], "source": [ "# 做一些随机取样\n", "for _ in range(10):\n", " print(c.perfect_sampling())" ] }, { "cell_type": "code", "execution_count": 10, "id": "c2c0bb84", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(\n", "[0.35355335+0.j 0.35355335+0.j 0.35355335+0.j 0.35355335+0.j\n", " 0.35355335+0.j 0.35355335+0.j 0.35355335+0.j 0.35355335+0.j], shape=(8,), dtype=complex64)\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[0.35355335+0.j 0.35355335+0.j 0.35355335+0.j 0.35355335+0.j\n", " 0.35355335+0.j 0.35355335+0.j 0.35355335+0.j 0.35355335+0.j]\n", "tensor([0.3536+0.j, 0.3536+0.j, 0.3536+0.j, 0.3536+0.j, 0.3536+0.j, 0.3536+0.j, 0.3536+0.j,\n", " 0.3536+0.j])\n" ] } ], "source": [ "# 我们可以轻松地从 NumPy 切换模拟后端!\n", "\n", "with tc.runtime_backend(\"tensorflow\") as K:\n", " c = get_circuit(3)\n", " print(c.state())\n", "\n", "with tc.runtime_backend(\"jax\") as K:\n", " c = get_circuit(3)\n", " print(c.state())\n", "\n", "with tc.runtime_backend(\"pytorch\") as K:\n", " # pytorch 后端无法保证最佳性能和完整功能\n", " c = get_circuit(3)\n", " print(c.state())" ] }, { "cell_type": "markdown", "id": "0cbe17e7", "metadata": {}, "source": [ "## 参数化量子电路(PQC)" ] }, { "cell_type": "code", "execution_count": 11, "id": "66192a2d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['r', 'cr', 'rx', 'ry', 'rz', 'crx', 'cry', 'crz', 'orx', 'ory', 'orz', 'any', 'exp', 'exp1']\n" ] } ], "source": [ "# 接受参数的量子电路门\n", "\n", "print(tc.Circuit.vgates)" ] }, { "cell_type": "code", "execution_count": 12, "id": "bae96276", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "r (theta: float = 0, alpha: float = 0, phi: float = 0) -> tensorcircuit.gates.Gate\n", "cr (theta: float = 0, alpha: float = 0, phi: float = 0) -> tensorcircuit.gates.Gate\n", "rx (theta: float = 0) -> tensorcircuit.gates.Gate\n", "ry (theta: float = 0) -> tensorcircuit.gates.Gate\n", "rz (theta: float = 0) -> tensorcircuit.gates.Gate\n", "crx (*args: Any, **kws: Any) -> Any\n", "cry (*args: Any, **kws: Any) -> Any\n", "crz (*args: Any, **kws: Any) -> Any\n", "orx (*args: Any, **kws: Any) -> Any\n", "ory (*args: Any, **kws: Any) -> Any\n", "orz (*args: Any, **kws: Any) -> Any\n", "any (unitary: Any, name: str = 'any') -> tensorcircuit.gates.Gate\n", "exp (unitary: Any, theta: float, name: str = 'none') -> tensorcircuit.gates.Gate\n", "exp1 (unitary: Any, theta: float, name: str = 'none') -> tensorcircuit.gates.Gate\n" ] } ], "source": [ "# 查看每种类型的变量门的关键字参数(类型为浮点数)\n", "for g in tc.Circuit.vgates:\n", " print(g, inspect.signature(getattr(tc.gates, g).f))" ] }, { "cell_type": "code", "execution_count": 13, "id": "55df5ffa", "metadata": {}, "outputs": [], "source": [ "def get_circuit(n, params):\n", " c = tc.Circuit(n) # 用 n 个量子比特初始化一个电路对象\n", " for i in range(n):\n", " c.rx(i, theta=params[i]) # 应用 rx 门\n", " c.cnot(0, 1)\n", " return c" ] }, { "cell_type": "code", "execution_count": 14, "id": "84392f01", "metadata": {}, "outputs": [], "source": [ "K = tc.set_backend(\"tensorflow\")" ] }, { "cell_type": "code", "execution_count": 15, "id": "24ba6d64", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(\n", "[ 0.6758712 +0.j 0. -0.36923012j 0. -0.36923015j\n", " -0.20171136-0.j -0.20171136+0.j 0. +0.11019541j\n", " 0. -0.36923015j -0.20171136-0.j ], shape=(8,), dtype=complex64)\n" ] } ], "source": [ "n = 3\n", "params = K.ones([n])\n", "c = get_circuit(n, params)\n", "print(c.state())" ] }, { "cell_type": "code", "execution_count": 16, "id": "c85cb07f", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[{'gatef': rx,\n", " 'index': (0,),\n", " 'name': 'rx',\n", " 'split': None,\n", " 'mpo': False,\n", " 'parameters': {'theta': <tf.Tensor: shape=(), dtype=complex64, numpy=(1+0j)>},\n", " 'gate': Gate(\n", " name: '__unnamed_node__',\n", " tensor:\n", " <tf.Tensor: shape=(2, 2), dtype=complex64, numpy=\n", " array([[0.87758255+0.j , 0. -0.47942555j],\n", " [0. -0.47942555j, 0.87758255+0.j ]], dtype=complex64)>,\n", " edges: [\n", " Edge('cnot'[2] -> '__unnamed_node__'[0] ),\n", " Edge('__unnamed_node__'[1] -> 'qb-1'[0] )\n", " ])},\n", " {'gatef': rx,\n", " 'index': (1,),\n", " 'name': 'rx',\n", " 'split': None,\n", " 'mpo': False,\n", " 'parameters': {'theta': <tf.Tensor: shape=(), dtype=complex64, numpy=(1+0j)>},\n", " 'gate': Gate(\n", " name: '__unnamed_node__',\n", " tensor:\n", " <tf.Tensor: shape=(2, 2), dtype=complex64, numpy=\n", " array([[0.87758255+0.j , 0. -0.47942555j],\n", " [0. -0.47942555j, 0.87758255+0.j ]], dtype=complex64)>,\n", " edges: [\n", " Edge('cnot'[3] -> '__unnamed_node__'[0] ),\n", " Edge('__unnamed_node__'[1] -> 'qb-2'[0] )\n", " ])},\n", " {'gatef': rx,\n", " 'index': (2,),\n", " 'name': 'rx',\n", " 'split': None,\n", " 'mpo': False,\n", " 'parameters': {'theta': <tf.Tensor: shape=(), dtype=complex64, numpy=(1+0j)>},\n", " 'gate': Gate(\n", " name: '__unnamed_node__',\n", " tensor:\n", " <tf.Tensor: shape=(2, 2), dtype=complex64, numpy=\n", " array([[0.87758255+0.j , 0. -0.47942555j],\n", " [0. -0.47942555j, 0.87758255+0.j ]], dtype=complex64)>,\n", " edges: [\n", " Edge(Dangling Edge)[0],\n", " Edge('__unnamed_node__'[1] -> 'qb-3'[0] )\n", " ])},\n", " {'gatef': cnot,\n", " 'gate': Gate(\n", " name: 'cnot',\n", " tensor:\n", " <tf.Tensor: shape=(2, 2, 2, 2), dtype=complex64, numpy=\n", " array([[[[1.+0.j, 0.+0.j],\n", " [0.+0.j, 0.+0.j]],\n", " \n", " [[0.+0.j, 1.+0.j],\n", " [0.+0.j, 0.+0.j]]],\n", " \n", " \n", " [[[0.+0.j, 0.+0.j],\n", " [0.+0.j, 1.+0.j]],\n", " \n", " [[0.+0.j, 0.+0.j],\n", " [1.+0.j, 0.+0.j]]]], dtype=complex64)>,\n", " edges: [\n", " Edge(Dangling Edge)[0],\n", " Edge(Dangling Edge)[1],\n", " Edge('cnot'[2] -> '__unnamed_node__'[0] ),\n", " Edge('cnot'[3] -> '__unnamed_node__'[0] )\n", " ]),\n", " 'index': (0, 1),\n", " 'name': 'cnot',\n", " 'split': None,\n", " 'mpo': False}]" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ir = c.to_qir()\n", "ir" ] }, { "cell_type": "code", "execution_count": 17, "id": "71ca41e2", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "<tf.Tensor: shape=(2, 2), dtype=complex64, numpy=\n", "array([[0.87758255+0.j , 0. -0.47942555j],\n", " [0. -0.47942555j, 0.87758255+0.j ]], dtype=complex64)>" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 查看量子门对应的矩阵\n", "ir[0][\"gatef\"](**ir[0][\"parameters\"]).tensor" ] }, { "cell_type": "code", "execution_count": 18, "id": "eb13a4ef", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(<tf.Tensor: shape=(), dtype=float32, numpy=0.2919265>, <tf.Tensor: shape=(3,), dtype=complex64, numpy=\n", "array([-4.5464873e-01+0.j, -4.5464873e-01+0.j, 2.2351742e-08+0.j],\n", " dtype=complex64)>)\n" ] } ], "source": [ "# 让我们组成一个可微分的量子函数\n", "\n", "\n", "def energy(params):\n", " c = get_circuit(n, params)\n", " return K.real(c.expectation([tc.gates.z(), [1]]))\n", "\n", "\n", "energy_vag = K.value_and_grad(energy)\n", "\n", "print(energy_vag(params))\n", "\n", "# 一旦我们有了梯度,我们就可以运行基于梯度的下降的变分优化" ] }, { "cell_type": "code", "execution_count": 19, "id": "1a82a3a1", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(<tf.Tensor: shape=(), dtype=float32, numpy=0.2919265>, <tf.Tensor: shape=(3,), dtype=complex64, numpy=\n", "array([-4.5464873e-01+0.j, -4.5464873e-01+0.j, 2.2351742e-08+0.j],\n", " dtype=complex64)>)\n" ] } ], "source": [ "# 并且使其可即时编译以加速\n", "\n", "energy_vag_jit = K.jit(K.value_and_grad(energy))\n", "\n", "print(energy_vag_jit(params))\n", "# 第一次运行可即时编译的函数会很慢,但是后面的测量会超级快" ] }, { "cell_type": "markdown", "id": "36c710ef", "metadata": {}, "source": [ "## 电路的高级用法" ] }, { "cell_type": "markdown", "id": "d4e55e05", "metadata": {}, "source": [ "### 输入状态\n", "\n", "我们可以从默认的 |0^n> 替换输入状态" ] }, { "cell_type": "code", "execution_count": 20, "id": "49865f13", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "<tf.Tensor: shape=(8,), dtype=complex64, numpy=\n", "array([0.49999997+0.j, 0.49999997+0.j, 0.49999997+0.j, 0.49999997+0.j,\n", " 0. +0.j, 0. +0.j, 0. +0.j, 0. +0.j],\n", " dtype=complex64)>" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "input_state = K.ones([2**n])\n", "input_state /= K.norm(input_state)\n", "\n", "c = tc.Circuit(n, inputs=input_state)\n", "c.H(0)\n", "c.state()" ] }, { "cell_type": "markdown", "id": "47f2a348", "metadata": {}, "source": [ "### 蒙特卡罗方法噪声模拟\n", "\n", "``tc.Circuit`` 支持使用蒙特卡罗方法进行噪声模拟,并且它也是可即时编译的! 此外,``tc.DMCircuit`` 支持使用全密度矩阵方法进行噪声模拟。" ] }, { "cell_type": "code", "execution_count": 21, "id": "e17b0b8b", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(0j, shape=(), dtype=complex64)\n" ] } ], "source": [ "c = tc.Circuit(n)\n", "for i in range(n):\n", " c.H(i)\n", "for i in range(n - 1):\n", " c.cnot(i, i + 1)\n", " c.depolarizing(i, px=0.1, py=0.1, pz=0.1)\n", " c.apply_general_kraus(tc.channels.phasedampingchannel(gamma=0.2), i + 1)\n", "print(c.expectation([tc.gates.y(), [1]]))" ] }, { "cell_type": "markdown", "id": "ae498792", "metadata": {}, "source": [ "### 应用任意幺正门\n", "\n", "只需直接使用 ``any`` API 通过提供相应的幺正矩阵" ] }, { "cell_type": "code", "execution_count": 22, "id": "1fed32f3", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "<tf.Tensor: shape=(8,), dtype=complex64, numpy=\n", "array([0.25+0.j, 0. +0.j, 0.25+0.j, 0. +0.j, 0.25+0.j, 0. +0.j,\n", " 0.25+0.j, 0. +0.j], dtype=complex64)>" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c = tc.Circuit(n)\n", "c.any(0, 1, unitary=K.ones([4, 4]) / K.norm(K.ones([4, 4])))\n", "c.state()" ] }, { "cell_type": "markdown", "id": "1d64546c", "metadata": {}, "source": [ "### 指数门\n", "\n", "如果我们想将门模拟为 $e^{i\\theta G}$ ,其中 $G^2=1$ 是一个矩阵,我们有一个快速有效的门实现,例如\n", "`exp1`" ] }, { "cell_type": "code", "execution_count": 23, "id": "32f50d3a", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "<tf.Tensor: shape=(8,), dtype=complex64, numpy=\n", "array([-0.14713009-3.2148516e-01j, 0.35355335+1.4901161e-08j,\n", " -0.14713009+3.2148516e-01j, 0.35355335-1.4901161e-08j,\n", " 0.35355335-1.4901161e-08j, -0.14713009+3.2148516e-01j,\n", " 0.35355335+1.4901161e-08j, -0.14713009-3.2148516e-01j],\n", " dtype=complex64)>" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c = tc.Circuit(n)\n", "for i in range(n):\n", " c.H(i)\n", "for i in range(n - 1):\n", " c.exp1(i, i + 1, theta=K.ones([]), unitary=tc.gates._zz_matrix)\n", "c.state()" ] }, { "cell_type": "markdown", "id": "934c3885", "metadata": {}, "source": [ "在上面的例子中 $G=Z\\otimes Z$" ] }, { "cell_type": "code", "execution_count": 24, "id": "409ed76b", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 1. 0. 0. 0.]\n", " [ 0. -1. 0. -0.]\n", " [ 0. 0. -1. -0.]\n", " [ 0. -0. -0. 1.]]\n" ] } ], "source": [ "print(tc.gates._zz_matrix)" ] }, { "cell_type": "markdown", "id": "ce35316b", "metadata": {}, "source": [ "下面列出了门模块中的常用矩阵" ] }, { "cell_type": "code", "execution_count": 25, "id": "f8c647b0", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "_cnot_matrix :\n", " [[1. 0. 0. 0.]\n", " [0. 1. 0. 0.]\n", " [0. 0. 0. 1.]\n", " [0. 0. 1. 0.]]\n", "_cy_matrix :\n", " [[ 1.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", " [ 0.+0.j 1.+0.j 0.+0.j 0.+0.j]\n", " [ 0.+0.j 0.+0.j 0.+0.j -0.-1.j]\n", " [ 0.+0.j 0.+0.j 0.+1.j 0.+0.j]]\n", "_cz_matrix :\n", " [[ 1. 0. 0. 0.]\n", " [ 0. 1. 0. 0.]\n", " [ 0. 0. 1. 0.]\n", " [ 0. 0. 0. -1.]]\n", "_fredkin_matrix :\n", " [[1. 0. 0. 0. 0. 0. 0. 0.]\n", " [0. 1. 0. 0. 0. 0. 0. 0.]\n", " [0. 0. 1. 0. 0. 0. 0. 0.]\n", " [0. 0. 0. 1. 0. 0. 0. 0.]\n", " [0. 0. 0. 0. 1. 0. 0. 0.]\n", " [0. 0. 0. 0. 0. 0. 1. 0.]\n", " [0. 0. 0. 0. 0. 1. 0. 0.]\n", " [0. 0. 0. 0. 0. 0. 0. 1.]]\n", "_h_matrix :\n", " [[ 0.70710678 0.70710678]\n", " [ 0.70710678 -0.70710678]]\n", "_i_matrix :\n", " [[1. 0.]\n", " [0. 1.]]\n", "_ii_matrix :\n", " [[1. 0. 0. 0.]\n", " [0. 1. 0. 0.]\n", " [0. 0. 1. 0.]\n", " [0. 0. 0. 1.]]\n", "_s_matrix :\n", " [[1.+0.j 0.+0.j]\n", " [0.+0.j 0.+1.j]]\n", "_swap_matrix :\n", " [[1. 0. 0. 0.]\n", " [0. 0. 1. 0.]\n", " [0. 1. 0. 0.]\n", " [0. 0. 0. 1.]]\n", "_t_matrix :\n", " [[1. +0.j 0. +0.j ]\n", " [0. +0.j 0.70710678+0.70710678j]]\n", "_toffoli_matrix :\n", " [[1. 0. 0. 0. 0. 0. 0. 0.]\n", " [0. 1. 0. 0. 0. 0. 0. 0.]\n", " [0. 0. 1. 0. 0. 0. 0. 0.]\n", " [0. 0. 0. 1. 0. 0. 0. 0.]\n", " [0. 0. 0. 0. 1. 0. 0. 0.]\n", " [0. 0. 0. 0. 0. 1. 0. 0.]\n", " [0. 0. 0. 0. 0. 0. 0. 1.]\n", " [0. 0. 0. 0. 0. 0. 1. 0.]]\n", "_wroot_matrix :\n", " [[ 0.70710678+0.j -0.5 -0.5j]\n", " [ 0.5 -0.5j 0.70710678+0.j ]]\n", "_x_matrix :\n", " [[0. 1.]\n", " [1. 0.]]\n", "_xx_matrix :\n", " [[0. 0. 0. 1.]\n", " [0. 0. 1. 0.]\n", " [0. 1. 0. 0.]\n", " [1. 0. 0. 0.]]\n", "_y_matrix :\n", " [[ 0.+0.j -0.-1.j]\n", " [ 0.+1.j 0.+0.j]]\n", "_yy_matrix :\n", " [[ 0.+0.j 0.-0.j 0.-0.j -1.+0.j]\n", " [ 0.+0.j 0.+0.j 1.-0.j 0.-0.j]\n", " [ 0.+0.j 1.-0.j 0.+0.j 0.-0.j]\n", " [-1.+0.j 0.+0.j 0.+0.j 0.+0.j]]\n", "_z_matrix :\n", " [[ 1. 0.]\n", " [ 0. -1.]]\n", "_zz_matrix :\n", " [[ 1. 0. 0. 0.]\n", " [ 0. -1. 0. -0.]\n", " [ 0. 0. -1. -0.]\n", " [ 0. -0. -0. 1.]]\n" ] } ], "source": [ "for name in dir(tc.gates):\n", " if name.endswith(\"_matrix\"):\n", " print(name, \":\\n\", getattr(tc.gates, name))" ] }, { "cell_type": "markdown", "id": "7851cdcd", "metadata": {}, "source": [ "### 非幺正门\n", "\n", "``tc.Circuit``由于其张量网络引擎性质而自动支持非幺正电路仿真" ] }, { "cell_type": "code", "execution_count": 26, "id": "e1805a84", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "<tf.Tensor: shape=(8,), dtype=complex64, numpy=\n", "array([0.83373 -0.9888977j, 0. +0.j ,\n", " 0.63496387-1.2984576j, 0. +0.j ,\n", " 0. +0.j , 0. +0.j ,\n", " 0. +0.j , 0. +0.j ], dtype=complex64)>" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c = tc.Circuit(n)\n", "c.exp1(1, unitary=tc.gates._x_matrix, theta=K.ones([]) + 1.0j * K.ones([]))\n", "c.state()" ] }, { "cell_type": "markdown", "id": "28222612", "metadata": {}, "source": [ "请注意,在这种情况下,最终量子态不再归一化。" ] }, { "cell_type": "code", "execution_count": 27, "id": "1581cf4f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Not equal to tolerance rtol=1e-07, atol=0\n", "\n", "Mismatched elements: 1 / 1 (100%)\n", "Max absolute difference: 0.93963802\n", "Max relative difference: 0.93963802\n", " x: array(1.939638+0.j, dtype=complex64)\n", " y: array(1.)\n" ] } ], "source": [ "try:\n", " np.testing.assert_allclose(K.norm(c.state()), 1.0)\n", "except AssertionError as e:\n", " print(e)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.0" } }, "nbformat": 4, "nbformat_minor": 5 }