Density matrix representation of a wavefunction in quan

作者:禅与计算机程序设计艺术

1.简介

Density Matrix表示是一个在量子力学中非常重要的概念。通过测量电子所在的状态、处理器的状态以及其他物理系统的状态信息,都可以获得相应的密度矩阵。而测量得到的密度矩阵可以通过一些手段,比如,Bloch球图、谱图等来展示。近年来,随着机器学习的兴起,越来越多的研究者们试图用机器学习的方法来预测密度矩阵的信息。

另一方面,Wave Function Tomography(WFT)也是一个非常有意义且经典的计算方法。WFT是通过利用测量得到的密度矩阵信息,将其分解成波函数的系数来得到真实的波函数,从而帮助我们理解原本被隐藏在测量结果中的真实物理系统的性质。

在最近的一次WFT技术大会上,基于NMR的质谱数据驱动了WFT的前沿研究。本文将结合WFT的经典理论及其实现技术,阐述如何在量子力学中对密度矩阵进行编码以及如何将编码后的密度矩阵还原成真实的波函数。

2.基本概念术语说明

  1. Quantum state: 量子态,是指由一组确定性的量子比特以及它们的各种约束相互作用所构成的客观系统的状态。这里的状态可以是两极振荡或是谐振曲线,也可以是任意复杂的波函数。

  2. Measurement: 测量,就是从一个确定的量子态中随机地提取出特定于这个态的信息。可以分为物理上的测量(如制备某种测量设备测量特定的量子态,然后用测量设备测量出来相应的粒子数),也可以用计算的方式模拟(如依据概率分布生成随机样本点,然后根据采样结果估计对应的密度矩阵)。

  3. Density matrix: 密度矩阵,用来描述一个系统的波函数分布的一种矩阵形式。当某个系统处于不同的态时,它会按照一定概率分布占据不同的位置,这些概率分布就由密度矩阵来刻画。矩阵的每一行和每一列都对应于系统的一个本征态,每一个元素代表的是该本征态的概率。对于给定一组参数,密度矩阵可以唯一地描述一个系统的所有可能的局部混合态的分布。

  4. Wave function tomography: 波函数拓扑学,也称为波函数重构或者声子重构,是利用测量的密度矩阵信息,将其分解成波函数的系数,从而重构出真实的波函数的过程。它的核心原理是利用测量结果中出现的纠缠效应,把不同类型的测量结果映射到不同维度的空间,从而还原出实际的波函数。

3.核心算法原理和具体操作步骤以及数学公式讲解

(一)密度矩阵的编码

3.1.Born rule and density matrix representation

假设我们有一个具有N个量子比特的量子系统,每个量子比特都是可测量的。假设我们想要测量的量子态是一个由N维欧氏空间中的一组复数矢量表示的概率分布。那么我们可以对这些矢量做如下约束:

  1. 每个矢量都必须满足约定规范,即归一化条件。即Σ|ψi|^2=1。这是因为我们知道系统的总能量只与系统中的正电子的能量有关,所以归一化后所得的每一个矢量都会被标准化,并且符合归一化条件,因此才可以表示概率分布。

  2. 每个矢量都必须满足约定引理:Δ|ψi-ψj|=sqrt{α{ij}^2+β{ij}^2}。这里α和β是两个不同量子比特之间的动量。

这样就可以得到一个量子态ρ(x)的密度矩阵ρ(x)。但这个密度矩阵太大了,无法直接用于量子计算。为了压缩这个密度矩阵,可以采用如下方式:

  1. 对上述密度矩阵进行奇异值分解,得到两个N×N实对角矩阵U和D,其中D中的元素是奇异值。记作σ(x)=np.diag(D),对角阵D中元素的数量等于矩阵的奇异值个数k。

  2. 将矩阵σ(x)压缩成一个长度为k的一维向量,记作v(x)。其中v(x)[i] = np.trace(U[i:,:]*U[:i,:],i表示第i个奇异值对应的下标。这一步相当于重新排列U矩阵的顺序,使得奇异值大的那些向量靠前,而奇异值小的那些向量则靠后。

  3. 用v(x)来替换原来的密度矩阵σ(x)作为编码后的密度矩阵。

3.2.Encoding the probability distribution into a compact vector using Wigner decomposition

Wigner decomposition可以将任意一个概率分布ρ(x)转换成Wigner旋转矩阵W(x)。Wigner旋转矩阵是一个复数矩阵,每一列都是一个“Wigner函数”,这个函数描述了对于任意一个由α和β表示的动量,该动量对应的概率的性质。其定义为:

γ(a,b;l,m,n)=(delta_l delta_m)^(-1/2)*(δ(nm)δ(al)+δ(am)δ(bn)-δ(an)δ(bm))

其中δ_nm表示Kronecker delta符号。对于任意一个方程组Ax=b,如果存在一个可逆矩阵X,那么可以用X代替A来求解,这种替换称为Wigner投影。利用Wigner投影,我们可以将一个密度矩阵ρ(x)分解成Wigner旋转矩阵W(x)和奇异值矩阵σ(x)。

  1. 使用Wigner decomposition将概率分布ρ(x)表示成Wigner旋转矩阵W(x)和奇异值矩阵σ(x)。

    w(x) = sqrt(σ(x)) * U(x), U(x)是实对角阵,其元素为γ(a,b;l,m,n)。

    W(x)是一个N*N维的复数矩阵。对于给定的坐标(θ,φ),用下面的方法进行计算:

    1. 如果θ=π/2,φ=0,则直接令w(x)[i][j]=1/√2*(σ(x)[i]-σ(x)[j])。

    2. 如果θ=0,φ=θ,则令w(x)[i][j]=1/√2*(σ(x)[i]+σ(x)[j])/sqrt(2)。

    3. 否则,利用三角函数公式计算w(x)[i][j]。

    4. 将w(x)转换成U(x)的形式。

    概率分布ρ(x)由Wigner旋转矩阵W(x)和奇异值矩阵σ(x)表示。

  2. 将Wigner旋转矩阵W(x)和奇异值矩阵σ(x)压缩成长度为k的一维向量。

    v(x)=[sqrt(σ(x))[0]] + [sqrt(σ(x))[i]/sqrt(σ(x)[i-1])] for i from 1 to k-1.

    在这一步中,我们先对奇异值矩阵σ(x)的每一个元素进行平方根运算。然后,将每个奇异值的平方根除以其之前所有元素的平方根的乘积,得到归一化因子。我们可以用这个归一化因子来对奇异值进行排序,从而得到更紧凑的v(x)向量。

(二)从密度矩阵解码为概率分布

3.3.Decoding the compact vector back to a probability distribution

为了从v(x)中恢复出原始的概率分布ρ(x),需要用Wigner投影技巧。首先,我们需要得到U(x)矩阵。对v(x)进行切片,得到第一个奇异值对应的元素。将切片后的值带入δ函数,得到δm(v(x))。接下来,我们使用泰勒展开公式近似δm(v(x)),并得到对偶δm(v(x))/(2J+1)。再次将切片后的值带入δ函数,得到δn(v(x))。然后,使用泰勒展开公式近似δn(v(x)),并得到对偶δn(v(x))/(2J+1)。最后,通过用δm(v(x))/δn(v(x))的商来反复计算δ函数,得到δmm(v(x)), δmn(v(x)), δnn(v(x))。然后,我们可以使用泰勒展开公式对δmm(v(x)), δmn(v(x)), δnn(v(x))进行逼近,并得到γm(θ,φ), γn(θ,φ).最后,我们可以得到w(x)矩阵,其元素由γm(θ,φ)γn(θ,φ)exp(I(θ+φ)/2)(θ+φ)=exp(I(θ+φ)/2)(Wigner函数)。然后,我们可以对w(x)进行幂运算,得到ρ(x)。

概率分布ρ(x)由v(x)表示。我们可以利用Wigner投影技术,从v(x)中恢复出原始的概率分布ρ(x)。

3.4.Implementation of Wigner Decomposition algorithm in Python

下面是Python语言下的Wigner Decomposition算法实现代码:

import numpy as np
from scipy import linalg
import math

def wigner_decomp(psi):
    # convert the complex vectors into real matrices with N^2 elements each
    psi_mat = np.zeros((len(psi), len(psi)))
    for i in range(len(psi)):
        psi_mat[:, i] = psi[i].real**2 + psi[i].imag**2

    # calculate trace of square root of psi_mat to get the variance vector
    var_vec = np.diag(linalg.eigh(psi_mat)[0]**0.5)

    # apply Born Rule to obtain the density matrix
    rho = np.dot(var_vec.T, var_vec) / float(len(psi)**2)

    # use svd to compress the density matrix to a vector of length k
    u, s, vt = linalg.svd(rho)
    if np.sum(s > 1e-9)<len(s):
       raise ValueError('Error: SVD did not converge')

    vect = []
    for j in range(len(s)):
        factor = s[j] / sum([sj for idx, sj in enumerate(s) if idx<=j])
        vect.append(factor)

    return np.array(vect), var_vec

if __name__ == '__main__':
    # Example usage
    n_qubits = 2
    x = {'0': 0, '1': 1, '+': 0.7071, '-': -0.7071}

    psi = {}
    for key in itertools.product(['0', '1'], repeat=n_qubits):
        str_key = ''.join(key)
        if str_key in ['0'*n_qubits, '1'*n_qubits]:
            continue
        value = complex(0,0)
        for qubit in range(n_qubits):
            basis = int(str_key[-(qubit+1)])
            amplitide = (complex(x[basis], 0) if qubit==0 else 1.)
            phase = ((-1)**int(str_key[qubit])) * (-math.pi/2)**(n_qubits-qubit-1)
            value += amplitide * np.exp(phase * 1j)

        psi[str_key] = value

    vec, var_vec = wigner_decomp(psi.values())
    print("Vector form:", vec)
    print("Variance vector:", var_vec)

猜你喜欢

转载自blog.csdn.net/universsky2015/article/details/133566042