{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# 量桨线性代数与量子信息模块简介\n", "*Copyright (c) 2023 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.*\n", "\n", "`linalg` 和 `qinfo` 模块是量桨封装各类矩阵操作和量子信息相关功能的模块。`linalg` 包含了矩阵的转置、共轭、迹等常用的函数,而 `qinfo` 模块则主要包含了偏迹,各类量子态的熵,保真度,迹距离等常见的量子信息相关的函数。" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## 矩阵的常见运算\n", "\n", "我们知道量子力学和线性代数有着密不可分的关联,在这里,我们通过简单的例子介绍量桨 `linalg` 模块和飞桨内常见的矩阵相关的运算函数。" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "c:\\Users\\liugeng02\\Anaconda3\\envs\\2023q2\\lib\\site-packages\\openfermion\\hamiltonians\\hartree_fock.py:11: DeprecationWarning: Please use `OptimizeResult` from the `scipy.optimize` namespace, the `scipy.optimize.optimize` namespace is deprecated.\n", " from scipy.optimize.optimize import OptimizeResult\n", "c:\\Users\\liugeng02\\Anaconda3\\envs\\2023q2\\lib\\site-packages\\paddle\\tensor\\creation.py:125: DeprecationWarning: `np.object` is a deprecated alias for the builtin `object`. To silence this warning, use `object` by itself. Doing this will not modify any behavior and is safe. \n", "Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations\n", " if data.dtype == np.object:\n", "c:\\Users\\liugeng02\\Anaconda3\\envs\\2023q2\\lib\\site-packages\\paddle\\tensor\\creation.py:125: DeprecationWarning: `np.object` is a deprecated alias for the builtin `object`. To silence this warning, use `object` by itself. Doing this will not modify any behavior and is safe. \n", "Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations\n", " if data.dtype == np.object:\n" ] } ], "source": [ "import paddle\n", "import paddle_quantum\n", "from paddle_quantum.state import State\n", "from paddle.linalg import eigvals, eig\n", "from paddle_quantum.linalg import dagger, NKron, density_matrix_random, unitary_random\n", "from paddle_quantum.qinfo import (\n", " partial_trace,\n", " state_fidelity,\n", " trace_distance,\n", " von_neumann_entropy,\n", " relative_entropy,\n", ")\n", "\n", "\n", "paddle_quantum.set_backend(\"density_matrix\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "我们先通过量桨内置的函数创建两个随机酉矩阵,在这里两个矩阵A和B均是 `paddle.Tensor` 形式。" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "矩阵A为:\n", "Tensor(shape=[2, 2], dtype=complex64, place=Place(cpu), stop_gradient=True,\n", " [[ (0.2921386957168579-0.1418590545654297j),\n", " (-0.7422900795936584+0.5861198306083679j)],\n", " [(0.9016497135162354-0.28558504581451416j),\n", " (0.28133758902549744-0.1622287780046463j)]])\n", "\n", "矩阵B为:\n", "Tensor(shape=[2, 2], dtype=complex64, place=Place(cpu), stop_gradient=True,\n", " [[(-0.30973920226097107-0.29339805245399475j),\n", " (0.8378809690475464+0.34049180150032043j) ],\n", " [ (0.8848108649253845-0.18732032179832458j) ,\n", " (0.3566453754901886-0.2341471016407013j) ]])\n" ] } ], "source": [ "A = unitary_random(num_qubits=1)\n", "B = unitary_random(num_qubits=1)\n", "print(f\"矩阵A为:\\n{A}\\n\")\n", "print(f\"矩阵B为:\\n{B}\")\n" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "**矩阵乘法**:矩阵乘法A*B有两种实现方式,第一种是使用paddle内部的 `matmul` 函数,第二种是直接使用 `@` 符号代表矩阵乘法。\n", "\n", "**矩阵转置**:计算矩阵A的转置可以使用 `A.t()`。\n", "\n", "**矩阵共轭**:计算矩阵A的共轭可以使用 `A.conj()` 。\n", "\n", "**矩阵的共轭转置**:计算一个矩阵的共轭转置有两种方法,一种是将两步操作分开,先后求取其共轭和转置 `A.conj().t()` ;另一种是直接调用量桨内部的 `dagger` 函数求取共轭转置。\n", "\n", "**矩阵的张量积**:矩阵的张量积 $A\\otimes B$ 可以使用 `paddle.kron()` 来计算。\n", "\n", "**多个矩阵的张量积**:多个矩阵的张量积可以使用量桨 `linalg` 内的 `NKron()` 来计算。\n", "\n", "**矩阵的迹**:对矩阵求迹可以使用 `paddle.trace()` 函数。\n", "\n", "**矩阵的偏迹**:对矩阵求偏迹可以使用量桨 `qinfo` 内的 `partial_trace()` 函数。\n", "\n", "**矩阵的特征值与特征向量**:矩阵的特征值和特征向量可以使用 `eig` 函数计算,也可以使用 `eigvals` 来单独计算矩阵的特征值。" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "multiplyAB_1 = paddle.matmul(A, B) # 矩阵乘法\n", "multiplyAB_2 = A @ B # 矩阵乘法\n", "A_transpose = A.t() # 矩阵的转置\n", "A_conjugate = A.conj() # 矩阵的共轭\n", "A_dagger = dagger(A) # 矩阵的共轭转置\n", "tensor_product_AB = paddle.kron(A, B) # 矩阵的张量积\n", "tensor_product_ABA = NKron(A, B, A) # 多个矩阵的张量积\n", "A_trace = paddle.trace(A) # 矩阵的迹\n", "partial_trace_matrix = partial_trace(tensor_product_AB, dim1=2, dim2=2, A_or_B=2) # 矩阵的偏迹\n", "eigenvalue, eigenvector = eig(A) # 矩阵的特征值与特征向量" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## 量子信息中的常见函数" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "我们先使用 `linalg` 里的 `density_matrix_random` 创建两个随机单比特量子态。" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "第一个量子态为:\n", " Tensor(shape=[2, 2], dtype=complex64, place=Place(cpu), stop_gradient=True,\n", " [[ (0.8994134664535522+0j) ,\n", " (-0.28608179092407227-0.09287679195404053j)],\n", " [(-0.28608179092407227+0.09287679195404053j),\n", " (0.10058653354644775+0j) ]])\n", "\n", "第二个量子态为:\n", " Tensor(shape=[2, 2], dtype=complex64, place=Place(cpu), stop_gradient=True,\n", " [[(0.17564187943935394+0j) ,\n", " (0.32964783906936646-0.1900634616613388j)],\n", " [(0.32964783906936646+0.1900634616613388j),\n", " (0.8243581056594849+0j) ]])\n" ] } ], "source": [ "state1 = density_matrix_random(1)\n", "print(f\"第一个量子态为:\\n {state1}\\n\")\n", "state2 = density_matrix_random(1)\n", "print(f\"第二个量子态为:\\n {state2}\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "我们利用 `state_fidelity()` 可以获得两个量子态之间保真度。" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "两个量子态之间的保真度为:\n", "Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True,\n", " [0.29595008])\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "c:\\Users\\liugeng02\\Anaconda3\\envs\\2023q2\\lib\\site-packages\\paddle\\fluid\\framework.py:1104: DeprecationWarning: `np.bool` is a deprecated alias for the builtin `bool`. To silence this warning, use `bool` by itself. Doing this will not modify any behavior and is safe. If you specifically wanted the numpy scalar type, use `np.bool_` here.\n", "Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations\n", " elif dtype == np.bool:\n" ] } ], "source": [ "fidelity = state_fidelity(state1, state2)\n", "print(f\"两个量子态之间的保真度为:\\n{fidelity}\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "值得注意的是,量桨有关量子态的函数兼容多种不同形式的输入,其形式可以是 `paddle.Tensor`, `numpy.ndarray`, 或是 `State`。同时,函数输出的格式与输入格式是匹配的,例如输入 `numpy.ndarray` 形式的数据将会同样获得 `numpy.ndarray` 形式的结果。" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.29595009466850986\n" ] } ], "source": [ "# 以numpy.ndarray形式输入\n", "state1 = state1.numpy()\n", "state2 = state2.numpy()\n", "print(state_fidelity(state1, state2))" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True,\n", " [0.29595008])\n" ] } ], "source": [ "# 以State形式输入\n", "state1 = State(state1)\n", "state2 = State(state2)\n", "print(state_fidelity(state1, state2))" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "利用 `trace_distance()` 我们可以计算两个量子态之间的迹距离" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "两个量子态之间的迹距离为:\n", "Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True,\n", " [0.95520324])\n" ] } ], "source": [ "TraceDistance = trace_distance(state1, state2)\n", "print(f\"两个量子态之间的迹距离为:\\n{TraceDistance}\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "使用 `von_neumann_entropy()` 可以计算量子态的冯诺依曼熵" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "量子态的冯诺依曼熵为:\n", "Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True,\n", " [0.])\n" ] } ], "source": [ "v_entropy = von_neumann_entropy(state2)\n", "print(f\"量子态的冯诺依曼熵为:\\n{v_entropy}\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "使用 `relative_entropy()` 可以计算两个量子态的相对熵" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "logm result may be inaccurate, approximate err = 1.2365573141431553e-07\n", "logm result may be inaccurate, approximate err = 2.1966168634145265e-08\n", "两个量子态之间的相对熵为:\n", "Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True,\n", " [23.84987831])\n" ] } ], "source": [ "r_entropy = relative_entropy(state1, state2)\n", "print(f\"两个量子态之间的相对熵为:\\n{r_entropy}\")" ] } ], "metadata": { "kernelspec": { "display_name": "2023q2", "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.16" }, "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2 }