PyQPanda

build status

一种功能齐全,运行高效的量子软件开发工具包

QPanda 2是由本源量子开发的开源量子计算框架,它可以用于构建、运行和优化量子算法。

QPanda 2作为本源量子计算系列软件的基础库,为OriginIR、Qurator、量子计算服务提供核心部件。

为了方便用户使用,QPanda 2为用户提供了Python版本的pyQPanda,本使用文档是pyQPanda的 教学文档,如希望学习C++版的QPanda 2,请参考 QPanda使用文档

量子计算背景

什么是量子计算

量子计算是一种遵循量子力学规律调控量子信息单元进行计算的新型计算模式,在理解量子计算的概念时,通常将它和经典计算相比较。

如图,经典计算使用2进制的数字电子方式进行运算,而二进制总是处于0或1的确定状态。

量子计算和现有的计算模式完全不同,它借助量子力学的叠加特性,能够实现计算状态的叠加,它不仅包含0和1,还包含0和1同时存在的叠加态。

_images/1.1.png

普通计算机中的2位寄存器在某一时间仅能存储4个二进制数(00、01、10、11)中的一个,而量子计算机中的2位量子位寄存器可同时存储这四种状态的叠加状态。

随着量子比特数目的递增,对于n个量子比特而言,量子信息可以处于2种可能状态的叠加,配合量子力学演化的并行性,可以展现比传统计算机更快的处理速度。

加上量子纠缠等特性,理论上,量子计算机相较于当前使用最强算法的经典计算机,在一些具体问题上,有更快的处理速度和更强的处理能力。

量子计算的发展

早在 1981 年,物理学家理查德·费曼(Richard Feynman)就提出了量子计算机的概念,他设想如果拓展一下计算机的工作方式,不使用逻辑门来建造计算机,而是一些其他的东西,比如分子和原子。 如果使用这些量子材料,它们具有非常奇异的性质,尤其是波粒二象性,是否能建造出模拟量子系统的计算机?于是他提出了这个问题并做了一些验证性实验,然后他推测,这个想法也许可以实现。由此,基于量子力学的新型计算机的研究被提上了科学发展的历程。

此后,计算机科学家们一直在努力攻克这一艰巨挑战。伴随时代发展的趋势,在20世纪90年代,量子计算机的算法发展得到了巨大的进步。

1992年Deutsch和Jozsa提出了D-J量子算法,开启了如今量子计算飞速发展的大幕。

1994年Peter Shor提出了Shor算法,这一算法在大数分解方面比目前已知的最有效的经典质因数分解算法快得多,因此对RSA加密极具威胁性,该算法带来巨大影响力的同时也进一步坚定了科学家们发展量子计算机的决心。

1996年Lov Grover提出了Grover量子搜索算法,该算法被公认为继Shor算法后的第二大算法。

2009年MIT三位科学家联合开发了一种求解线性系统的HHL量子算法。众所周知,线性系统是很多科学家和工程领域的核心,由于HHL算法在特定条件下实现了相较于经典算法有指数加速效果,这是未来能够在机器学习,人工智能科技得以突破的关键性技术。

_images/history.png

随着上述量子计算理论的探索,硬件也在飞速发展,2013年加拿大D-Wave系统公司发布了512比特的量子计算设备。

2016年,IBM发布了6量子比特的可编程量子计算机。

2017年本源量子发布了32位量子计算虚拟系统,同时还建立了以32位量子计算虚拟系统为基础的本源量子计算云平台。

2018年初Intel和Google分别测试了49位和72位量子芯片。

2018年12月6日,本源量子发布了第一款测控一体机Origin Quantum AIO,不仅提高了综合量子测控能力,更节约了量子测控环节各种大型设备的空间,为量子计算行业的高精尖仪器带来了更多的可能。

2019年1月,IBM发布了世界上第一台独立的量子计算机IBM Q System One。

2020年9月12日,本源量子完全自主开发的超导量子计算云平台正式向全球用户开放,该平台基于本源量子自主研发的超导量子计算机——本源悟源(搭载6比特超导量子处理器夸父 KF C6-130)。

量子计算机的发展目标

根据量子计算机的发展趋势,目前量子计算机的发展可以大致分为 3 个阶段:

第一阶段:能够对大约 50 个量子比特进行有效操纵,并且在实验上可以在特定问题的求解上展现出“量子优越性”,这一阶段目前已经实现;

第二阶段:由于量子计算机在运算过程中极易受到外界的干扰,因此需要大量冗余的量子比特来实现运算中的量子纠错,人们预计需要对几百个量子比特进行有效操纵,从而实现量子纠错的关键技术,并且进一步探索量子计算的实际应用场景;

第三阶段:需要对大约 10~100 万量级的量子比特进行有效操纵,从而构建可编程的通用量子计算机,并且最终实现加密密钥破解以及最佳优化搜索等。

9月10日,在国内量子计算领域占据重要一席的本源量子发布未来五年量子计算技术规划路线图。

_images/develop.png

路线图显示,到2025年,本源量子将突破1000位量子比特,达到1024位量子比特,这将意味着专用量子计算机的形成,并将实际运用到一些行业领域中。

量子计算理论基础

对于一个非物理专业的人而言,量子力学概念晦涩难懂。鉴于此,本章节仅介绍量子力学的一些基础概念加之部分数学的相关知识,甚至不涉及薛定谔方程,就足够开始量子计算机的应用。 这如同不需去了解CPU的工作原理以及经典计算机的组成原理,但仍能在日常生活中使用经典计算机或者编写经典程序一样。

量子态

量子(quantum)是现代物理学的重要概念。即一个物理量如果存在最小的不可分割的基本单位,此最小单位称为量子. 量子具有四个基本特性,了解其特性也有助于我们更好地理解量子的本质。

量子具有如下特性:
  • 量子化:描述物体长度时,一定会遇到最小的不可分割的基本单位,这一现象也称为量子化

  • 跃迁:当一个原子中的电子获得来自原子外的能量时,它就有可能克服能级之间的能量差距,跳到另外一个态上面

  • 量子叠加态:对于量子本身,它能同时存在于很多状态的叠加上

  • 测量和坍塌:测量会影响这个粒子本身的状态

量子态是一个微观粒子的状态。可用线性代数中的向量来描述量子态,在量子理论 中,描述量子态的向量称为态矢,态矢分为左矢和右矢。

\[\begin{split}\begin{aligned} \text{ket} & |\psi\rangle =[c_{1},c_{2},\cdots, c_{n}]^{T}\\ \text{bra} & \langle\psi| =[c_{1}^{*},c_{2}^{*},\cdots, c_{n}^{*}] \end{aligned}\end{split}\]

相应地,内积与外积定义为:设 \(|\alpha\rangle=[a_{1},a_{2},\cdots, a_{n}]^{T}\)\(|\beta\rangle=[b_{1},b_{2},\cdots, b_{n}]^{T}\)

\[\begin{split}\begin{aligned} \text{} & \langle\alpha \vert\beta\rangle =\sum_{i=1}^{n}a_{i}b_{i}\\ \text{} & |\alpha\rangle \langle\beta| =\left[a_{i}b_{j}^{*}\right]_{n\times n} \end{aligned}\end{split}\]

量子比特

量子比特是量子计算中的基本单元. 一个量子比特(qubit)就是二维复向量空间 \(\mathbb{C}^{2}\) 中一个单位向量.设 \(|0\rangle=[1,0]^{T}\) , \(|1\rangle=[0,1]^{T}\)\(\mathbb{C}^{2}\) 的一组基,则一个量子比特可以表示为

\[\begin{aligned}\label{equ:Psi} |\psi\rangle=\alpha|0\rangle+\beta|1\rangle, \end{aligned}\]

其中,\(\alpha,\beta\in\mathbb{C}\)\((\alpha,\beta)\ne (0,0)\)\(\vert\alpha\vert^2+\vert\beta\vert^2=1\)\(\alpha,\beta\) 称为振幅。 并且 \(\vert\alpha\vert^2+\vert\beta\vert^2=1\)

纯态和混合态

我们看到的具有精确已知状态的量子系统均是纯态(pure state)。 所以纯态 \(|\psi\rangle\) 可以用向量表示,且其密度矩阵表示为 \(\rho=|\psi\rangle\langle\psi|\) ,以100%的概率处在状态 \(|\psi\rangle\)

如果系统并非处于一个态中,而是以 \(p_{i}\) 的概率处于 \(|\psi_{i}\rangle(i=1,\cdots,n)\) ,这种状态无法用一个态矢量来描述,称之为混合态。其密度矩阵表示为:

\[\begin{aligned} \rho_{mix}=\sum_{i} p_{i}|\psi_{i}\rangle\langle\psi_{i}|. \end{aligned}\]

综上所述,对于纯态它可以借助向量和密度矩阵两种形式进行描述。但是对于混合态,只能借助密度矩阵的形式进行描述。易知混合态不是叠加态,叠加态不是混合态;纯态可以是本征态,也可以是叠加态。

纯态具有如下性质:

  • 1.密度矩阵 \(\rho\) 是幂等的,即 \(\rho^{2}=|\psi\rangle\langle\psi|\psi\rangle\langle\psi|=\rho\)

  • 2.在任意正交基下的 \(\rho\) 的迹 \(tr(\rho)=\sum_{i}\langle i|\rho|i\rangle=\sum_{i}\langle i|\psi\rangle\langle\psi|i\rangle=\langle\psi|\psi\rangle=1\) ,进而 \(tr(\rho^{2})=1\)

  • 3.厄米特性:\(\rho^{\dagger}=\rho\)

  • 4.半正定性:\(\langle\phi|\rho|\phi\rangle=\langle\phi|\psi\rangle\langle\phi|\psi\rangle=|\langle\phi|\psi\rangle|^2\ge 0\)

混合态具有如下性质:

  • 1.密度矩阵 \(\rho_{mix}\) 是非幂等的,即 \(\rho_{mix}^{2}\ne\rho_{mix}\)

  • 2.在任意正交基下的 \(\rho_{mix}\) 的迹 \(tr(\rho_{mix})=1\) (所有可能的测量结果的相加)

  • 3.满足 \(tr(\rho_{mix}^{2})< 1\) (证明过程中用Schwartz不等式即可证得)

  • 4.厄米特性与半正定性

通过布洛赫球,可以更直观地理解纯态与混合态。球面上每一个点都能映射到一个纯态, 球内每一个点都能映射到混合态,完全混合 态(也称为最大混合态)是球心,它意味着这里不存在任何量子叠加性,具体可见下图

_images/pure_state.png

酉变换

酉变换是一种矩阵,也是一种操作,它作用在量子态上得到的是一个新的量子态。使用 \(U\) 来表达酉矩阵, \(U^{\dagger}\) 表示酉矩阵的转置复共轭矩阵,二者满足运算关系 \(UU^{\dagger}=I\) ,所以酉矩阵的转置复共轭矩阵也是一个酉矩阵,说明酉变换是一种可逆变换。

一般酉变换在量子态上的作用是变换矩阵左乘以右矢进行计算的。例如一开始有一个量子态 \(|\psi_{0}\rangle\) , 经过酉变换 \(U\) 之后得到 \(|\psi\rangle=U\left|\psi_{0}\right\rangle\)

或者也可以写为

\[\langle\psi|=\left\langle\psi_{0}\right| U^{\dagger}\]

由此可见,两个矢量的内积经过同一个酉变换之后保持不变。

\[\langle\varphi \mid \psi\rangle=\langle\varphi|U^{\dagger}U| \psi\rangle\]

类似地,也可以通过酉变换表示密度矩阵的演化;

\[\rho=U{\rho_{0}} U^{\dagger}\]

这样就连混合态的演化也包含在内了。

量子态的测量

对量子态进行测量会导致坍塌,即测量会影响到原来的量子态,因此量子态的全部信息不可能通过一次测量得到.

下面,我们给出测量的通用计算表达式。

假设:量子测量是由测量算子(measurement operators)的集合 \(\{M_{i}\}\) 来描述,这些算子可以作用在待测量系统的状态空间(state space)上。 指标i表示在实验上可能发生的结果. 如果测量前的量子系统处在最新状态 \(|\psi\rangle\) ,那么测量结果i发生的概率为

\[\begin{aligned} p(i)=\langle \psi|M_{i}^{\dagger}M_{i}|\psi\rangle \end{aligned}\]

并且测量后的系统状态转变为

\[\begin{aligned} \dfrac{M_{i}|\psi\rangle}{\sqrt{\langle\psi|M_{i}^{\dagger}M_{i}|\psi}\rangle} \end{aligned}\]

由于所有可能情况的概率和为1,即

\[\begin{aligned} \sum_{i}p(i)=\sum_{i}\langle \psi|M_{i}^{\dagger}M_{i}|\psi\rangle=1 \end{aligned}\]

则测量算子需满足

\(\sum_{i}M_{i}^{\dagger}M_{i}=I\) 。该方程被称为完备性方程(completeness equation).

量子测量有多种方式,如投影测量(projective measurements)、正算子值测量 (Positive Operator-Valued Measure). 投影测量要求测量算子为投影算子 \(\{P_{i}\}\) ,且满足 \(P_{i}^{\dagger}P_{i}=P_{i}^{2}=P_{i}\) 。 正算子值测量并非全新的概念,对于任意的测量算子 \(\{M_{i}\}\) ,我们记 \(E_{i}=M_{i}^{\dagger}M_{i}\) ,可以看出E是正定的,且是完备的( \(\sum_{i}E_{i}=I\) ),然后我们把 \(\{E_{i}\}\) 叫做正算子值测量. 可以说,投影测量与正算子值测量是一般测量的特例. 当测量算子具有酉矩阵时,投影测量和一般测量等价. 当测量算子是酉矩阵时,投影测量和一般测量等价.

这里介绍一下投影测量. 投影测量由一个可观测量(observable) \(\Lambda\) 来描述,可观测量是一个待观测系统 的状态空间上的自伴算子. 对可观测量 \(\Lambda\) 作谱分解

\[\begin{aligned} \Lambda=\sum_{i}\lambda_{i}P_{i} \end{aligned}\]

这里 \(\Lambda_{i}\)\(\Lambda\) 在特征值 \(\lambda_{i}\) 对应的特征空间上的投影. 在对状态 \(|\psi\rangle\) 测量之后,得到结果i的概率为

\[\begin{aligned} p(i)=p(\lambda=\lambda_{i})=\langle\psi|P_{i}|\psi\rangle \end{aligned}\]

若测量后,结果i发生,则量子系统最新的状态为

\[\begin{aligned} \dfrac{\Lambda_{i}|\psi\rangle}{\sqrt{p_{i}}} \end{aligned}\]

投影测量有一个重要的特征就是很容易计算投影测量的平均值以及标准差:

\[E(\Lambda)=\sum_{i}\lambda_{i}p_{i}= \sum_{i}\lambda_{i}\langle\psi|P_{i}|\psi\rangle=\langle\psi|\Lambda|\psi\rangle\]
\[\Delta(\Lambda)^{2}= E(\Lambda^{2})- E(\Lambda)^{2}=\langle\psi|\Lambda^{2}|\psi\rangle-\langle\psi|\Lambda|\psi\rangle^{2}\]

若对量子态 \(|\psi\rangle\) 进行测量,测量结果为0的概率为

\[p(0)=\langle\psi|M_{0}^{\dagger}M_{0}|\psi\rangle=\langle\psi|M_{0}|\psi\rangle=\vert \alpha \vert^{2}\]

对应测量后的状态为

\[\dfrac{M_{0}|\psi\rangle}{\sqrt{\langle\psi|M_{0}^{\dagger}M_{0}|\psi}\rangle}=\dfrac{M_{0}|\psi\rangle}{|\alpha|}=\dfrac{\alpha}{|\alpha|}|0\rangle\]

同理可得到以概率 \(\vert \beta \vert^2\) 处于 \(|1\rangle\) ,对应测量后的状态为 \(\frac{\beta}{|\beta|}|1\rangle\)

对于投影测量,若可观测量是 \(X=\begin{bmatrix}0 & 1\\ 1 & 0 \end{bmatrix}\) ,现对待观测量 \(|\psi\rangle=\alpha|0\rangle+\beta|1\rangle\) 进行投影测量。

对X作谱分解得到 \(\Lambda=\lambda_{1}P_{1}+\lambda_{2}P_{2}\) ,其中 \(\lambda_{1}=1,\lambda_{2}=-1\) 以及投影算子 \(P_{1}=\begin{bmatrix} \frac{1}{2} & \frac{1}{2}\\ \frac{1}{2} & \frac{1}{2} \end{bmatrix},P_{2}=\begin{bmatrix} \frac{1}{2} & -\frac{1}{2}\\ -\frac{1}{2} & \frac{1}{2} \end{bmatrix}\)

在对状态 \(|\psi\rangle\) 测量,可得到概率为 \(p(1)=p(\lambda=\lambda_{1})=\langle\psi|P_{1}|\psi\rangle=\frac{1}{2}(\alpha+\beta)^{2}\) 以及 \(p(2)=p(\lambda=\lambda_{2})=\langle\psi|P_{2}|\psi\rangle=\frac{1}{2}(\alpha-\beta)^{2}\)

若测量后,结果1发生,则量子系统最新的状态为

\[\begin{aligned} \dfrac{P_{1}|\psi\rangle}{\sqrt{p_{1}}}=\frac{\sqrt{2}}{2}(|0\rangle+|1\rangle)=|+\rangle \end{aligned}\]

结果2发生,则量子系统最新的状态为

\[\begin{aligned} \dfrac{P_{2}|\psi\rangle}{\sqrt{p_{2}}}=\frac{\sqrt{2}}{2}(|0\rangle-|1\rangle)=|-\rangle \end{aligned}\]

量子计算机

目前主流的量子计算芯片技术研发路线有超导量子计算机和半导体量子计算机两种。

超导量子芯片

超导量子计算是基于超导电路的量子计算方案,其核心器件是超导约瑟夫森结。超导量子电路在设计、制备和测量等方面,与现有的集成电路技术具有较高的兼容性,对量子比特的能级与耦合可以实现非常灵活的设计与控制,极具规模化的潜力。

由于近年来的迅速发展,超导量子计算已成为目前最有希望实现通用量子计算的候选方案之一。超导量子计算实验点致力于构建一个多比特超导量子计算架构平台,解决超导量子计算规模化量产中遇到的难题。

超导电路类似于传统的电子谐振电路,这种谐振电路产生了谐振子的能级。超导约瑟夫森效应使得超导电路在不发生损耗和退相干的情况下产生非线性,非线性导致谐振子的能级间隔不再等同,其中最低的两个能级可以用来实现量子比特的操控。

超导量子计算的研究始于2000年前后,后来在美国耶鲁大学Schoelkopf和Devoret研究组的推动下,将超导比特和微波腔进行耦合,实现了量子比特高保真度的读出和纠缠,加速了超导量子比特的研究。微波腔是一种容纳微波光子的谐振腔,比特的两个能级会对微波腔的光子产生扰动,这一信号的扰动就可以用来实现比特信号的读出。比特和比特之间还可以通过微波腔相连,当两个比特和腔是强耦合状态的时候,两个比特就会通过腔发生相互作用,物理学家通过这一相互作用实现了两比特操作。在2009年,基于超导比特和腔的耦合,实现了两比特的高保真度量子算法,使得超导量子计算得到了世界的广泛关注。

从2014年开始,美国企业界开始关注超导量子比特的研究,并加入了研究的大潮中。2014年9月,美国Google公司与美国加州大学圣芭芭拉分校合作研究超导量子比特,使用X-mon形式的超导量子比特

2017年,Google发布了实现量子计算机对经典计算机的超越——“量子霸权”的发展蓝图。2018年年初,其设计了72比特的量子芯片,并着手进行制备和测量,这是向实现量子霸权迈出的第一步。在Google公司加入量子计算大战的同时,美国国际商用机器有限公司(IBM)于2016年5月在云平台上发布了他们的五比特量子芯片。

2017年,IBM制备了20比特的芯片,并展示了用于50比特芯片的测量设备,同时也公布了对BeH2分子能量的模拟,表明了在量子计算的研究上紧随Google的步伐,不仅如此,IBM还发布了QISKit的量子软件包,促进了人们通过经典编程语言实现对量子计算机的操控。

2020年,本源量子发布自主研发、自主可控的的新一代超导量子计算机——本源悟源(搭载6比特超导量子处理器夸父 KF C6-130)。

_images/origin_quantum_computer.jpg

除了美国Google公司和IBM公司外,美国Intel公司和荷兰代尔夫特理工大学也合作设计了17比特和49比特超导量子芯片,并在2018年的CES大会上发布,不过具体的性能参数还有待测试;美国初创公司Rigetti发布了19比特超导量子芯片,并演示了无人监督的机器学习算法,使人们见到了利用量子计算机加速机器学习的曙光。

半导体量子芯片

由于经典计算机主要基于半导体技术,基于半导体开发量子计算也是物理学家研究的重点领域。相比超导量子计算微米级别的比特大小,量子点量子比特所占的空间是纳米级别,类似于大规模集成电路一样,更有希望实现大规模的量子芯片。现在的主要方法是在硅或者砷化镓等半导体材料上制备门控量子点来编码量子比特。编码量子比特的方案多种多样,在半导体系统中主要是通过对电子的电荷或者自旋量子态的控制实现。

与超导量子计算类似,半导体量子计算也正在从科研界转向工业界,2016年,美国芯片巨头Intel公司开始投资代尔夫特理工大学的硅基量子计算研究,目标是在五年内制备出第一个二维表面码结构下的逻辑量子比特;2017年,澳大利亚也组建了硅量子计算公司,目标是五年内制备出第一台10比特硅基量子计算机。

在国内,中国科学技术大学的郭国平研究组在传统的GaAs基量子比特方面积累了成熟的技术,实现了多达3个电荷量子比特的操控和读出,并基于电荷量子比特制备了品质因子更高的杂化量子比特,实现对国际水平的追赶,并为进一步的超越做准备。

概述

QPanda是一种功能齐全,运行高效的量子软件开发工具包,作为一款开源的量子计算框架,它可以用于构建、运行和优化量子算法。 QPanda提供的功能有:

  • 量子计算编程基础组件 : QPanda提供了丰富的量子计算编程基础组件,包括量子比特和量子门操作。开发者可以使用这些组件来构建复杂的量子算法,从简单的量子门序列到更复杂的量子电路。这些基础组件为开发者提供了构建量子计算任务所需的核心工具。

  • 高性能量子虚拟机 : QPanda的高性能量子虚拟机允许开发者在经典计算机上进行高效的量子模拟。这种虚拟机能够快速模拟量子算法的执行过程,使开发者能够在不依赖实际量子硬件的情况下测试和优化他们的算法。

  • 算法组件介绍 : QPanda提供了多种量子算法组件的介绍,包括量子搜索、量子优化等。这些算法组件的介绍帮助开发者了解如何使用QPanda来实现不同类型的量子计算任务。通过这些介绍,开发者可以更快地上手并开始构建自己的量子算法。

  • 量子芯片和高性能集群模拟 :提供了本源高性能计算集群的模拟服务以及悟源真实芯片的量子计算服务。

pyqpanda是python版本的QPanda,通过pybind11工具,以一种直接和简明的方式,对QPanda2中的函数、类进行封装,并且提供了几乎完美的映射功能。 封装部分的代码在QPanda2编译时会生成为动态库,从而可以作为python的包引入。

开始使用pyqpanda

系统配置和安装

为了兼容 高效便捷,QPanda2提供了C++ 和 Python两个版本,本文中主要介绍python版本的使用。 如要了解和学习C++版本的使用请移步 QPanda2

系统配置

pyqpanda是以C++为宿主语言,其对系统的环境要求如下:

Windows

software

version

Microsoft Visual C++ Redistributable x64

2015

Python

>= 3.8 && <= 3.11

Linux

software

version

GCC

>= 5.4.0

Python

>= 3.8 && <= 3.11

下载pyqpanda

如果你已经安装好了python环境和pip工具, 在终端或者控制台输入下面命令:

pip install pyqpanda

备注

在linux下若遇到权限问题需要加 sudo

备注

在ubuntun高版本环境可能会出现libffi库导入失败问题,需要安装合适版本的libffi,通过 conda install -c conda-forge libffi

更新日志

3.8.3.2 - 2024-04-03

新增功能和重要更新:

1.调整了基准测试三个算法接口参数和用法,包括 单双门随机基准测试 , 双门交叉熵基准测试 ,和 量子体积QV ,具体可以参考 量子体积

2.本源量子云计算服务新增了混合加密配置使用选项,用于对量子计算任务传输和通信中的任务数据开启 混合加密 从而保护数据安全和隐私,可以根据需要选择开启或打开。

开启方式为:将 QCloud 初始化函数的参数 enable_pqc_encryption 设置为 True 即可,默认为 False 不开启。

from pyqpanda import *

machine = QCloud()
machine.set_configure(72,72)

machine.init_qvm(token=my_api_key, enable_pqc_encryption=True)

当今,随着量子计算机在硬件技术、纠错方法、算法理论与应用等多个维度的不断进步,传统的公钥算法由于无法抵御量子计算机的攻击逐渐变得脆弱,面临着被未来量子计算机攻击的风险。为了提供更强大的安全保护,本源量子云平台引入了一种端到端的 后量子(PQC)混合加密 方法,以保护云服务的用户端和服务端之间的信息传输,在有效抵御量子计算机的各种攻击的同时考虑了现有后量子密码极低但潜在的风险,并借助融合传统公钥密钥(RSA类、ECC类)算法规避了这一隐患。

混合加密: 混合加密是一种结合了两种密码算法的模式,该模式或部分或完整地继承各部分密码模块的某些特性,用于混合的两个功能相近的算法可以均为经典密码算法,也可以同时来自PQC。考虑到现有公钥密码算法面对量子计算机的脆弱性以及现阶段PQC算法潜在的风险,混合算法的两部分“原料”一般一半来自经典,一半来自PQC。例如,苹果于最近推出的iMessage加密方案以及谷歌在其浏览器中部署的混合加密方案均为Kyber(PQC的一种)与ECC类算法的混合。

本源量子云采用的混合加密方法来自NIST将要形成标准的 格基密码算法Kyber 以及 ECC类算法 ,并且在具体的实现过程中尽量采用国家认证的SM系列算法,例如,ECC类算法选取SM2算法,混合流程中用以密钥导出的函数(KDF)选用SM3算法,建立会话密钥后后续加解密采用SM4算法,并使用了安全度较高的CBC模式。

3.解决了部分情况下由于全局虚拟机导致的originir转换异常

4.电路模块可视化完善,包括:
  • 修复导出text偶尔丢失量子逻辑门的错误

  • 对png格式下自定义名称过长进行限制

3.8.3 - 2024-03-01

新增功能和重要更新:

1.量子线路可视化新增模块化导出接口,支持线路模块化命名、展示和输出

import pyqpanda as pq
from ..pyqpanda.Visualization.circuit_composer import CircuitComposer

def test_append():
    circ1 = CircuitComposer(n_qubits)
    circuit = pq.QCircuit()
    circuit << pq.H(q[0]) << pq.CNOT(q[0], q[1]) << pq.CNOT(q[1], q[2])
    circ1.append(circuit)
    circ1 << pq.BARRIER(q)
    circ1.append(pq.QFT(q[3:]), "QFT")
    circ1.append(pq.deep_copy(circ1))
    print(circ1)
    print(circ1.circuit)

    a = circ1.draw_circuit("pic", "test.png")
    b = circ1.draw_circuit("latex")
    c = circ1.draw_circuit("text")
    print(b)
    print(c)

if __name__ == '__main__':
    n_qubits = 6
    qvm = pq.CPUQVM()
    qvm.init_qvm()
    q = qvm.qAlloc_many(n_qubits)

    test_append()

2.修改了量子虚拟机初始化错误,该错误会导致多个量子虚拟机重复初始化过程引发未知异常,涉及到的虚拟机有张量网络虚拟机,部分振幅虚拟机,单振幅虚拟机,密度矩阵模拟器和Clifford模拟器等

3.解决了mac部分python环境(3.10,3.11)下的包的导入异常问题

4.修改了量子比特池初始化和清空操作不彻底的错误,该错误会导致清空后设置最大容量时内存异常

3.8.2.3 - 2024-01-05

新增功能和重要更新:

1.量子云计算服务芯片任务添加了相关限制,单个任务的层数不能超过 500 层,并且单门控制比特数量不能超过 2 个(Toffoli门除外), 双门不支持添加控制比特,如果量子线路中有相关计算需求,需要先调用多控门分解接口 ldd_decompose ,参考如下代码:

import numpy as np
from pyqpanda import *

online_api_key = "XXX"

machine = QCloud()
machine.set_configure(72,72);

# online
machine.init_qvm(online_api_key,True)

q = machine.qAlloc_many(6)
c = machine.cAlloc_many(6)

measure_prog = QProg()
measure_prog << X(q[1])\
            << X(q[2])\
            << H(q[0]).control([q[1], q[2], q[3]])\
            << CNOT(q[0], q[1])\
            << CNOT(q[1], q[2]).control([q[1], q[2], q[3]])\
            << Measure(q[0], c[0])

decomposed_prog = ldd_decompose(measure_prog)
measure_result = machine.real_chip_measure(decomposed_prog, 1000, real_chip_type.origin_72)

print(measure_result)

3.8.2 - 2024-01-05

新增功能和重要更新:

1.量子计算服务适配了本源悟空芯片上线,并且可以支持originir量子程序参数, real_chip_type.origin_72 即为72比特芯片类型,使用方法可以参考 真实芯片计算服务

machine = QCloud()
machine.set_configure(72,72);

# online, xxx 替换为实际的用户api_token
machine.init_qvm("XXX",False)

qlist = machine.qAlloc_many(6)
clist = machine.cAlloc_many(6)

# 构建量子程序,可以手动输入,也可以来自OriginIR或QASM语法文件等
measure_prog = QProg()
measure_prog << H(qlist[0])\
            << CNOT(qlist[0], qlist[1])\
            << CNOT(qlist[1], qlist[2])\
            << Measure(qlist[0], clist[0])\
            << Measure(qlist[1], clist[1])\
            << Measure(qlist[2], clist[2])

batch_prog = [measure_prog for _ in range (6)]

pmeasure_prog = QProg()
pmeasure_prog << H(qlist[0])\
            << CNOT(qlist[0], qlist[1])\
            << CNOT(qlist[1], qlist[2])

prog_string = convert_qprog_to_originir(measure_prog, machine)
originir_list = [convert_qprog_to_originir(prog, machine) for prog in batch_prog]

real_chip_measure_result = machine.real_chip_measure(measure_prog, 1000, real_chip_type.origin_72)
originir_result =  machine.real_chip_measure(prog_string, 1000, real_chip_type.origin_72)

print(real_chip_measure_result)
print(originir_result)

2.ldd多控门分解接口( ldd_decompose )适配了RXX,RYY,RZX,RZZ,MS等特殊双门以及 QOracle 的受控形式,示例程序如下

from pyqpanda import *
from scipy.stats import unitary_group

machine = CPUQVM()
machine.init_qvm()
q = machine.qAlloc_many(5)
c = machine.cAlloc_many(5)

prog = QProg()
prog << random_qcircuit(q, 10)

# 生成任意酉矩阵
unitary_matrix = unitary_group.rvs(2**2,random_state=169384)

prog << X([q[2], q[3], q[4]])\
    << RXX(q[0], q[1], 1).control([q[2], q[3], q[4]])\
    << RYY(q[0], q[1], 2).control([q[2], q[3], q[4]])\
    << QOracle([q[0], q[1]], unitary_matrix).control([q[2], q[3], q[4]])

in_matrix = get_unitary(prog)

def compare_complex_lists(list1, list2, tolerance=1e-6):
    array1 = np.array(list1)
    array2 = np.array(list2)

    real_close = np.allclose(array1.real, array2.real, atol=tolerance)
    imag_close = np.allclose(array1.imag, array2.imag, atol=tolerance)
    return real_close and imag_close

out_matrix = get_unitary(ldd_decompose(prog))

import numpy as np
if(compare_complex_lists(in_matrix, out_matrix)):
    print("ldd_decompose success.")

其他更新:

1.修复了ISWAP的dagger形式在多个虚拟机下的计算结果错误 2.修复了部分情况下pyqpanda导入依旧需要libcurl的问题

3.8.1 - 2023-12-25

新增功能和重要更新:

1.新增了稀疏态量子态初态接口,用于稀疏方式进行初态制备,需要满足初态归一化条件,代码示例:

machine = CPUQVM()
machine.set_configure(72,72);

machine.init_qvm()

qlist = machine.qAlloc_many(6)
clist = machine.cAlloc_many(6)

sparse_state = {'000000' : 0.5 + 0.5j, '000001' : 0.5 + 0.5j}
machine.init_sparse_state(sparse_state, qlist)

prog = QProg()
prog << I(qlist[0])

machine.directly_run(prog)
probs = machine.get_qstate();

print(probs)

2.量子云虚拟机添加了批量任务提交,目前仅可用于芯片任务的批量任务提交。

machine = QCloud()
machine.set_configure(72,72);

#xxx替换为量子云用户token
machine.init_qvm("XXX", True)

qlist = machine.qAlloc_many(6)
clist = machine.cAlloc_many(6)

measure_prog = QProg()
measure_prog << hadamard_circuit(qlist)\
            << CZ(qlist[0], qlist[1])\
            << Measure(qlist[0], clist[0])\
            << Measure(qlist[1], clist[1])\
            << Measure(qlist[2], clist[2])

batch_prog = [measure_prog for _ in range (6)]

pmeasure_prog = QProg()
pmeasure_prog  << hadamard_circuit(qlist)\
            << CZ(qlist[0], qlist[1])

batch_measure_result = machine.real_chip_measure_batch(batch_prog, 1000, real_chip_type.origin_72);
print(batch_measure_result)

3.虚拟机计算模拟和originir指令添加了Mlmer–Srensen"逻辑门(MS门)

MS q[0],q[1]

4.新增了CircuitComposer,用于优化打印时的信息显示

import pyqpanda as pq
from pyqpanda import circuit_composer

def test_append():
    circ1 = CircuitComposer(n_qubits)
    circuit = pq.QCircuit()
    circuit << pq.H(q[0]) << pq.CNOT(q[0], q[1]) << pq.CNOT(q[1], q[2])
    circ1.append(circuit)
    circ1 << pq.BARRIER(q)
    circ1.append(pq.QFT(q[3:]), "QFT")

    print(circ1)
    print(circ1.circuit)

if __name__ == '__main__':
    n_qubits = 6
    qvm = pq.CPUQVM()
    qvm.init_qvm()
    q = qvm.qAlloc_many(n_qubits)

    test_append()

其他更新:

1.修复量子虚拟机set_configure设置与init的冲突,该问题会导致部分情况下的内存泄露

3.8.0 - 2023-10-31

更新和代码改动内容:

1.新增量子程序关于单双门数、层数、总逻辑门数量相关的统计接口 count_prog_info ,示例

# 统计 QProg 的信息
prog_info = count_prog_info(my_qprog)

# 统计 QCircuit 的信息,并启用优化
optimized_info = count_prog_info(my_qcircuit, optimize=True)

# 获取统计结果的各种属性
num_layers = prog_info.layer_num
num_gates = prog_info.gate_num
num_double_gates = prog_info.double_gate_num
# ... 其他属性获取

基于分层统计的量子程序数据分析,可用于评估量子程序的运行时间、深度及复杂度,有利于更好的对量子算法进行改进, 该接口同时提供了较为全面的可视化输出接口,具体可参考 量子程序统计

  1. 基于Clifford的 stabilizer 模拟器添加了噪声模拟,目前仅支持比特翻转,相位反转,比特相位反转,去极化以及相位阻尼这五个噪声模型,具体可以参考下面的代码和 稳定器与Clifford模拟器 中的接口介绍。

    from pyqpanda import *
    
    machine = Stabilizer()
    machine.set_configure(72,72)
    
    machine.init_qvm()
    
    qlist = machine.qAlloc_many(6)
    clist = machine.cAlloc_many(6)
    
    measure_prog = QProg()
    measure_prog << X(qlist[0])\
                << X(qlist[1])\
                << CNOT(qlist[1], qlist[2])\
                << CNOT(qlist[2], qlist[3])\
                << measure_all(qlist, clist)
    
    machine.set_noise_model(NoiseModel.BITFLIP_KRAUS_OPERATOR,GateType.PAULI_X_GATE,0.2)
    print(machine.run_with_configuration(measure_prog,10000))
    
  2. 将pyqpanda中关于算法部分全部移植到 pyqpanda-algorithm 算法库,这个是一个独立于pyqpanda的算法模块包,详细模块和接口功能具体可见 pyqpanda-algorithm

  3. 密度矩阵噪声设置现在可以正确叠加,参考如下代码:

    machine = DensityMatrixSimulator()
    machine.init_qvm()
    
    prog = QProg()
    q = machine.qAlloc_many(2)
    c = machine.cAlloc_many(2)
    
    prog.insert(X(q[0]))\
        .insert(CNOT(q[0], q[1]))
    
    density_matrix1 = machine.get_density_matrix(prog)
    
    # case 1 expectation: 00 -> 0.42 , 11 -> 0.58
    machine.set_noise_model(NoiseModel.BITFLIP_KRAUS_OPERATOR, GateType.PAULI_X_GATE, 0.3)
    machine.set_noise_model(NoiseModel.BITFLIP_KRAUS_OPERATOR, GateType.PAULI_X_GATE, 0.3)
    density_matrix2 = machine.get_density_matrix(prog)
    
  4. ClassicalCondition添加c_and、c_or、c_not功能,用于构建量子逻辑分支程序时实现复杂的表达式判断,可以参考下面的代码

    p = QProg();
    p << H(qubits[0]) \
        << CNOT(qubits[0], qubits[1]) \
        << H(qubits[2]) \
        << Measure(qubits[0], cbits[0])\
        << Measure(qubits[1], cbits[1])\
        << Measure(qubits[2], cbits[2])
    
    true_prog1 = QProg();
    true_prog2 = QProg();
    true_prog3 = QProg();
    true_prog4 = QProg();
    
    true_prog3 << X(qubits[2]);
    
    if_prog3 = create_if_prog((cbits[0] == 0).c_and(cbits[1] == 0).c_and(cbits[2] == 0), true_prog3)
    

修复和解决的问题:

  1. 修复量子态编码中关于复数数据重载函数在python中调用出现丢失虚部,导致只索引double类型接口错误。

  2. 解决某些使用GPU虚拟机情况下,cuda与Eigen3的运行冲突问题

  3. 修改了经典寄存器部分情况下有误,造成无法使用qif和qwhile的问题

  4. 优化了量子线路映射和转化过程中的错误

  5. 解决CPUQVM部分初始化和虚拟机释放场景下使用引入的内存泄漏问题

  6. 解决了部分映射接口在使用时异常出现程序崩溃和死循环的错误

  7. 修改了所有模拟器可能在计算含有BARRIER的量子程序过程中出错的问题

  8. 解决控制swap逻辑门,进行多控门分解时,控制信息丢失问题

3.7.17.1 - 2023-7-25

**本次小版本更新重点解决的问题如下: **

1.量子门统计相关接口,添加对枚举和整型的兼容性支持

from numpy import pi
from pyqpanda import *

machine = CPUQVM()
machine.init_qvm()

q = machine.qAlloc_many(3)
c = machine.cAlloc_many(3)

prog = QProg()
prog =random_qprog(2,2,10,machine,q)

count_result = count_qgate_num(prog, 7)

#上版运行结果:报错,提示数据类型不兼容
#本次更新结果:正常运行得到结果

print(count_result)

2.解决单个比特在释放时(qFree接口)程序异常退出的严重性bug

from numpy import pi
from pyqpanda import *

machine = CPUQVM()

machine.init_qvm()

q = machine.qAlloc_many(3)
c = machine.cAlloc_many(3)

machine.qFree(q[0])

#上版运行结果:程序异常退出
#本次更新结果 : 程序正常结束

print("qFree success")

3.修复了qasm相关指令集转化接口,在重复调用时比特重复申请的异常

from numpy import pi
from pyqpanda import *

machine = CPUQVM()
machine.init_qvm()

# 编写QASM文件
f = open('test_qasm.txt', mode='w',encoding='utf-8')
f.write("""// test QASM file
    OPENQASM 2.0;
    include "qelib1.inc";
    qreg q[2];
    creg c[2];
    x q[0];
    x q[1];
    """)
f.close()

for i in range(5):

    prog_trans, qv, cv = convert_qasm_to_qprog("test_qasm.txt", machine)
    print(prog_trans)

#上版运行结果:每次的线路比特都不一样
#本次更新结果 : 每次的线路完全相同

3.7.17 - 2023-5-22

新增功能和重要更新:

1.新增 Clifford模拟器 ,主要用于基础量子纠错场景以及高比特且稀疏的Clifford门集构成的量子线路模拟,具体接口可以参考 稳定器与Clifford模拟器

2.量子云虚拟机相关更新

(1)为了适配了新版本的本源量子云平台做了相关改动,对每个用户的认证标识符做了签名加密处理,但接口使用方式与之前相同 (2)完善相关的错误处理,现在出错和异常信息输出更加具体明确

3.新增Pauli算符与矩阵的转化接口,通过矩阵转换Pauli算符接口名为 matrix_decompose_hamiltonian ,示例如下:

import pyqpanda as pq
import numpy as np

matrix = np.array([[2,1,4,2],[1,3,2,6],[4,2,2,1],[2,6,1,3]])
hamiltonian = pq.matrix_decompose_hamiltonian(matrix)
print(hamiltonian)

4.提供一种利用矩阵乘积态(MPS)的低秩表达近似分布振幅制备算法,可以通过一种较少的CNOT的门完成对分布振幅的表达,并且这种表达是一种近邻接形式,因此可以直接作用于芯片,由于双门个数的减少,也有利于增加分布制备的成功率。

import pyqpanda as pq
import numpy as np

N = 6
machine = pq.CPUQVM()
machine.init_qvm()
q = machine.qAlloc_many(N)
input = np.random.rand(2**N)
input = input/np.linalg.norm(input)
print(input)
cir_encode = pq.Encode()
cir_encode.approx_mps(q,input)

# 测保真度
print(cir_encode.get_fidelity(input))

#获取对应的线路
cir=cir_encode.get_circuit()
#input
[0.16112594 0.16100983 0.1400971  0.17698809 0.00271532 0.03514281
0.21320235 0.16615301 0.05702894 0.00801802 0.1383352  0.19258674
0.17222723 0.04907042 0.08964018 0.18973404 0.19969125 0.04078985
0.09852639 0.0812352  0.01124633 0.15024028 0.0052733  0.08204391
0.13542787 0.0063939  0.01784828 0.20612599 0.00029431 0.11172891
0.03021631 0.04188075 0.11371365 0.01309453 0.15079619 0.10912272
0.10914789 0.09004797 0.14673464 0.01355957 0.14773146 0.06804273
0.18411989 0.11896504 0.20181007 0.14760838 0.01292288 0.05372168
0.16185868 0.0282684  0.20429462 0.15065767 0.00913953 0.05270058
0.14767897 0.05914504 0.14426304 0.17902859 0.14117762 0.14085366
0.16269993 0.11606257 0.18384488 0.08961622]

#保真度
0.9900438487247981

5.Pauli算符的构造函数现在提供可选参数,用于决定是否合并同类项,同时也可以显式调用手动合并函数

import pyqpanda as pq
import numpy as np

#默认不合并同类项
operator = pq.PauliOperator({"X0 Y2" : -0.044750,
                            "Z0 Z1" : 0.189766,
                            "Z1 Z0" : 0.270597,
                            "Z3" : -0.242743})

print(operator)

#合并同类项
operator = pq.PauliOperator({"X0 Y2" : -0.044750,
                            "Z0 Z1" : 0.189766,
                            "Z1 Z0" : 0.270597,
                            "Z3" : -0.242743},True)

print(operator)

#手动合并
operator.reduce_duplicates()

输出结果如下:

#默认不合并同类项
{
    "X0 Y2" : -0.044750,
    "Z0 Z1" : 0.189766,
    "Z0 Z1" : 0.270597,
    "Z3" : -0.242743
}

#合并同类项
{
    "X0 Y2" : -0.044750,
    "Z0 Z1" : 0.460363,
    "Z3" : -0.242743
}

上述可选合并默认参数的使用方式适用于以下Pauli算符的构造函数

import pyqpanda as pq
import numpy as np

operator = pq.PauliOperator({"X0 X1" : -0.044750, "Z0 Z1" : 0.189766}, True)
operator = pq.PauliOperator(np.array([0, 1, 1, 0]).reshape(2, 2), True)
operator = pq.PauliOperator("X0 X1", 0.122, True)

其他更新:

1.修复在某些情况下,GPU虚拟机无法在linux下运行的问题

2.修复pyqpanda画量子线路时,Barrier门会出现比特和图像不符的现象

3.在编译优化方面,解决了高深度量子线路编译时,偶尔出现的内存崩溃问题

4.修复部分振幅虚拟机,分解Toffoli门和CU门无法正确识别分解结果的问题,现在部分振幅虚拟机对全部的单双门和Toffoli门均有很好地支持

5.噪声虚拟机添加线程数量控制

6.解决密度矩阵噪声在算符类噪声施加比特参数的错误

3.7.16 - 2023-1-12

新增功能和重要更新:

1.新增 密度矩阵模拟器 ,适用于小型量子系统下的密度矩阵模拟,同时提供约化密度矩阵,概率分布,哈密顿量期望以及噪声线路模拟等接口,具体可以参考 密度矩阵模拟器

2.优化了泡利算符的构造方式,新增了通过矩阵来构造泡利算符的接口。

3.优化了泡利算符的构造方式,新增了形如 operator = 1.5 * x(0) + 0.6 * y(1) + 2.1 * z(2) 的更简洁的构造方式。

4.单振幅虚拟机添加获取对应振幅接口。

其他更新

1.修复在只有measure线路等情况下,输出latex信息显示和转换失败的问题。

2.更新变分组件,添加三角函数相关接口。

3.优化了获取矩阵接口,现在可以添加了量子比特可选参数,获取一个量子线路中指定比特对应的矩阵。

4.修复退相干噪声计算错误的问题。

5.修复某些情况下GPU模拟器运行错误问题。

6.修复ISWAP门默认参数未统一的问题。

7.删除Encode类中归一化函数,并修改为入参检测归一化。

pyqpanda相关项目

作为一款开源量子计算编程框架,pyqpanda为开发者提供了高效、易用的工具,以便在量子计算领域开展研究和应用。PyQpanda 提供了丰富的功能和特性,使得在量子算法、量子模拟和量子程序设计方面都能够得到有效的支持。

除了提供基本的量子编程功能,pyqpanda在其他项目中的应用也具有重要意义,具体如下:

pyqpanda-algorithm

pyqpanda-algorithm是基于pyqpanda的量子算法开发和运行环境工具包。为开发者提供了一套标准化的工具,让他们可以编写量子程序,这些程序可以很容易地移植到不同的量子计算平台上。是发展量子软件和推进量子计算研究的重要资源。

py-vqnet

深度学习是实现人工智能的一种现代方法。实现机器学习任务的框架有很多,但是计算资源限制了机器学习的性能。量子计算提供了一种革新计算机的方法,量子计算机可以利用量子理论、叠加和纠缠的特性来进行与经典计算机完全不同的计算。使用量子计算机加速机器学习训练是一种具备前瞻性的方法。

VQNet是本源量子软件开发团队基于经典的机器学习开发的一种可高效连接机器学习和量子算法的量子机器学习框架,可满足构建所有类型的量子机器学习算法。

基于经典的机器学习,VQNet在量子经典机器学习区域中生成了一个通用架构,融合了传统的机器学习任务和可变量子线路(Variational Quantum Circuit, VQC)。该框架让用户能够用一种常见的操作来构建量子线路,例如矩阵乘法,并允许前向和反向传播。用户能够将可训练的量子操作实现到神经网络中。该框架可实现量子-经典混合任务的训练,为量子机器学习开辟了一个新的领域。

py-chemiq

pyChemiQ就像是一款化学计算器,研究人员可以利用这款软件来计算材料合成与生物制药中的化学过程,便捷地利用量子计算机的算力解决和研究化学问题。

目前pyChemiQ提供丰富的功能和python API接口,包括:

  • 支持输入分子结构得到二次量子化后的Fermion Hamiltonian

  • 丰富的映射功能:Jordan-Wigner变换、Bravyi-Kitaev变换、Parity变换和Multilayer Segmented Parity(MSP) 变换

  • 多种拟设方法:Unitary Coupled Cluster(UCC)、Hardware-Efficient、symmetry-preserved

  • 不同优化器可选择:NELDER-MEAD、POWELL、COBYLA、L-BFGS-B、SLSQP和Gradient-Descent

量子逻辑门


经典计算中,最基本的单元是比特,而最基本的控制模式是逻辑门。我们可以通过逻辑门的组合来达到我们控制电路的目的。类似地,处理量子比特的方式就是量子逻辑门。 使用量子逻辑门,我们有意识的使量子态发生演化。所以量子逻辑门是构成量子算法的基础。

量子逻辑门由酉矩阵表示。最常见的量子门在一个或两个量子位的空间上工作,就像常见的经典逻辑门在一个或两个位上操作一样。

单比特的门可以用以下形式表达:

\[\begin{aligned} |\psi\rangle=\alpha|0\rangle+\beta|1\rangle \end{aligned}\]

其中 \(\alpha\)\(\beta\) 是复数,在测量中,比特出现在 \(|0\rangle\) 的概率是 \(|\alpha|^2\)\(|1\rangle\) 的概率是 \(|\beta|^2\) 。作为向量表示为:

\[\begin{split}\begin{aligned} |\psi\rangle=\left(\begin{array}{l}\alpha \\ \beta\end{array}\right) \end{aligned}\end{split}\]

由于概率守恒 \(|\alpha|^2+|\beta|^2=1\) ,并且因为无法检测到全局相位 \(|\psi\rangle:=e^{i\delta}|\psi\rangle\) 。 我们只需要两个实数就能描述单量子比特量子态。

一个便捷的表示方法是

\[\begin{aligned} |\psi\rangle=\cos(\theta/2)|0\rangle+\sin(\theta/2)e^{i\phi}|1\rangle \end{aligned}\]

其中 \(0\leq\phi<2\pi\) , \(0\leq\theta\leq\pi\) 。由此可见,在量子比特态和单位球面上的点之间存在一一对应关系,这就是量子比特态的布洛赫球表示法。

量子门通常用矩阵表示,作用于一个量子比特的门由一个 \(2\times2\) 单元矩阵表示,将表示门的矩阵与表示量子态的矢量相乘,就能得到量子门的功能。

\[\begin{aligned} |\psi^{\prime}\rangle=U|\psi\rangle \end{aligned}\]

一般酉矩阵能够使 \(|0\rangle\) 到上述状态。即

\[\begin{split}\begin{aligned} U=\begin{bmatrix} cos(\theta/2) & a \\ e^{i\phi}sin(\theta/2) & b \end{bmatrix}\quad \end{aligned}\end{split}\]

a和b是复数,其约束条件是: \(0\leq\theta\leq\pi\)\(0\leq\phi<2\pi\) 对于所有的 \(U^\dagger U=I\) 。这样就会得到三个约束条件: \(a\to-e^{i\lambda}\sin(\theta/2), b\to e^{i\lambda+i\phi}\cos(\theta/2),\) 其中 \(0\leq\lambda<2\pi\)

\[\begin{split}\begin{aligned} U(\theta,\phi,\lambda)=\begin{pmatrix} cos\left(\frac\theta2\right) & -e^{i\lambda}\sin\left(\frac\theta2\right) \\ e^{i\phi}\sin\left(\frac\theta2\right) & e^{i(\phi+\lambda)}\cos\left(\frac\theta2\right)\end{pmatrix} \end{aligned}\end{split}\]
\[ \begin{align}\begin{aligned}\begin{aligned}\\\end{aligned}\end{aligned}\end{align} \]

常见量子逻辑门矩阵形式

单比特量子逻辑门

I门

又称为Id门或者Identity门。I门没有任何作用,适用于任何量子线路的任意地方。

这个门主要有两个使用途径:

  1. 一个是在计算的时候经常使用。比如在证明两个门的矩阵是互逆矩阵的时候经常用到;

  2. 在讨论实际的硬件操作时,“没有作用”等价于“无操作”。

I
I
\(\begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix}\quad\)

Phase门

P
P
\(\begin{bmatrix} 1 & 0 \\ 0 & e^{i\theta} \end{bmatrix}\quad\)

P门,又称为相位门,是可以设置参数的门。需要向其输入正确的数字( \(\theta\) )。 P门是以Z轴为基准,旋转 \(\theta\)

\[\begin{aligned} p(\lambda)= U(0, 0, \lambda) \end{aligned}\]

Hadamard门

常用来对单一量子比特做基地变换,同时产生产生叠加态。

\[\begin{split}\begin{aligned} H = \frac{1}{\sqrt{2}} \begin{pmatrix} 1 & 1\\ 1 & -1 \end{pmatrix}= U(\pi/2,0,\pi) \end{aligned}\end{split}\]
H
Hadamard
\(\begin{bmatrix} 1/\sqrt {2} & 1/\sqrt {2} \\ 1/\sqrt {2} & -1/\sqrt {2} \end{bmatrix}\quad\)

X门的作用是将状态0和1的振幅进行转换。

\[\begin{split}\begin{aligned} X &= \begin{pmatrix} 0 & 1\\ 1 & 0 \end{pmatrix}= U(\pi,0,\pi) \end{aligned}\end{split}\]

Y门的作用是在Bloch球中以y轴为中心旋转 \(\pi\)

\[\begin{split}\begin{aligned} Y &= \begin{pmatrix} 0 & -i\\ i & 0 \end{pmatrix}=U(\pi,\pi/2,\pi/2) \end{aligned}\end{split}\]

Z门的作用是在Bloch球中以z轴为中心旋转 \(\pi\)

\[\begin{split}\begin{aligned} Z &= \begin{pmatrix} 1 & 0\\ 0 & -1 \end{pmatrix}=P(\pi) \end{aligned}\end{split}\]
X
Pauli-X
\(\begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix}\quad\)
Y
Pauli-Y
\(\begin{bmatrix} 0 & -1i \\ 1i & 0 \end{bmatrix}\quad\)
Z
Pauli-Z
\(\begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix}\quad\)
X1
X1
\(\begin{bmatrix} 1/\sqrt {2} & -1i/\sqrt {2} \\ -1i/\sqrt {2} & 1/\sqrt {2} \end{bmatrix}\quad\)
Y1
Y1
\(\begin{bmatrix} 1/\sqrt {2} & -1/\sqrt {2} \\ 1/\sqrt {2} & 1/\sqrt {2} \end{bmatrix}\quad\)
Z1
Z1
\(\begin{bmatrix} e^{-i\pi/4} & 0 \\ 0 & e^{i\pi/4} \end{bmatrix}\quad\)
\[\begin{split}\begin{aligned} R_x(\theta) = \begin{pmatrix} \cos(\theta/2) & -i\sin(\theta/2)\\ -i\sin(\theta/2) & \cos(\theta/2) \end{pmatrix} = U(\theta, -\pi/2,\pi/2) \end{aligned}\end{split}\]
\[\begin{split}\begin{aligned} R_y(\theta) = \begin{pmatrix} \cos(\theta/2) & - \sin(\theta/2)\\ \sin(\theta/2) & \cos(\theta/2) \end{pmatrix} =U(\theta,0,0) \end{aligned}\end{split}\]
\[\begin{split}\begin{aligned} R_z(\phi) = \begin{pmatrix} e^{-i \phi/2} & 0 \\ 0 & e^{i \phi/2} \end{pmatrix}\equiv P(\phi) \end{aligned}\end{split}\]
RX
RX
\(\begin{bmatrix} \cos(\theta/2) & -1i×\sin(\theta/2) \\ -1i×\sin(\theta/2) & \cos(\theta/2) \end{bmatrix}\quad\)
RY
RY
\(\begin{bmatrix} \cos(\theta/2) & -\sin(\theta/2) \\ \sin(\theta/2) & \cos(\theta/2) \end{bmatrix}\quad\)
RZ
RZ
\(\begin{bmatrix} e^{-i\theta/2} & 0 \\ 0 & e^{i\theta/2} \end{bmatrix}\quad\)

T,S门

T门作为经常使用的门,是 \(\theta = \pi/4 的P门。在Bloch球中,绕z轴旋转\pi/4\)

\[\begin{split}\begin{aligned} T = \begin{pmatrix} 1 & 0\\ 0 & i \end{pmatrix}= P(\pi/4) \end{aligned}\end{split}\]
\[\begin{split}\begin{aligned} T^{\dagger} = \begin{pmatrix} 1 & 0\\ 0 & -i \end{pmatrix}= P(-\pi/4) \end{aligned}\end{split}\]

S门也是P门的一种情况,为 \(\theta = \pi/2\) 的P门。在Bloch球中,绕z轴旋转 \(\pi/2\)

\[\begin{split}\begin{aligned} S = \begin{pmatrix} 1 & 0\\ 0 & i \end{pmatrix}= P(\pi/2) \end{aligned}\end{split}\]
\[\begin{split}\begin{aligned} S^{\dagger} = \begin{pmatrix} 1 & 0\\ 0 & -i \end{pmatrix}= P(-\pi/2) \end{aligned}\end{split}\]
T
T
\(\begin{bmatrix} 1 & 0 \\ 0 & e^{i\pi / 4} \end{bmatrix}\quad\)
S
S
\(\begin{bmatrix} 1 & 0 \\ 0 & e^{i\pi / 2} \end{bmatrix}\quad\)

U门

上述很多门都是P门的特殊情况,而在所有单一比特的量子门中最为常见的是 \(U_3\) 门。 本章所有的门都可以通过调整 \(U_3\) 门的参数来实现。

\[\begin{split}\begin{aligned} U(\theta, \phi, \lambda) = \begin{pmatrix} \cos\left(\frac{\theta}{2}\right) & -e^{i\lambda}\sin\left(\frac{\theta}{2}\right) \\ e^{i\phi}\sin\left(\frac{\theta}{2}\right) & e^{i(\phi+\lambda)}\cos\left(\frac{\theta}{2}\right) \end{pmatrix} \end{aligned}\end{split}\]

在pyqpanda中也可以直接通过使用 \(U_1, U_2, U_3, U_4\) 。来调用相关量子门。

\[\begin{split}\begin{aligned} U1(\lambda) &= P(\lambda) = U(0, 0, \lambda) \\ U2(\phi, \lambda) &= U(\frac{\pi}{2}, \phi, \lambda)\\ U3(\theta, \phi, \lambda) &= U(\theta, \phi, \lambda)\\ U4(\alpha, \beta, \gamma, \delta) &= e^{-i*(\alpha+(\beta+\delta)/2)}U3(\gamma, \delta, \lambda) \end{aligned}\end{split}\]

U1

U1

\(\begin{bmatrix} 1 & 0 \\ 0 & e^{i\theta} \end{bmatrix}\quad\)

U2

U2

\(\begin{bmatrix} 1/\sqrt {2} & -e^{i\lambda}/\sqrt {2} \\ e^{i\phi}/\sqrt {2} & e^{i\lambda+i\phi}/\sqrt {2} \end{bmatrix}\quad\)

U3

U3

\(\begin{bmatrix} \cos(\theta/2) & -e^{i\lambda}\sin(\theta/2) \\ e^{i\phi}\sin(\theta/2) & e^{i\lambda+i\phi}\cos(\theta/2) \end{bmatrix}\quad\)

U4

U4

\(\begin{bmatrix} e^{i*(\alpha-(\beta+\delta)/2)}*cos(\gamma/2) & -e^{i*(\alpha-(\beta-\delta)/2)}*sin(\gamma/2) \\ e^{i*(\alpha+(\beta-\delta)/2)}*sin(\gamma/2) & e^{i*(\alpha+(\beta+\delta)/2)}*cos(\gamma/2) \end{bmatrix}\quad\)


RPhi门

在NISQ时代,量子计算机无法做到任意逻辑门的运行。因此需要将其转化为量子芯片所支持的基础逻辑门集合以实现通用计算。在本源量子芯片中所支持的单双门组合则为 \(U_3\)\(CZ\) 。因此,在编译量子程序时,QPanda会对非基础逻辑门进行转换,转换方法如下所示。

首先,定义 \(\phi\)\(XY`\) 平面内某一旋转轴与 \(X\) 正向的夹角,则对任意 \(XY\) 旋转门,有:

\[\begin{split}\begin{aligned} R_\phi(\theta) = cos\frac{\theta}{2}I - i sin\frac{\theta}{2}(cos\phi\sigma_x + sin\phi\sigma_y) = \begin{bmatrix} cos\frac{\theta}{2} & -i sin\frac{\theta}{2}e^{-i\phi} \\ -isin\frac{\theta}{2}e^{i\phi} & cos\frac{\theta}{2} \end{bmatrix} \end{aligned}\end{split}\]

Z旋转门的形式如下:

\[\begin{split}\begin{aligned} RZ(\theta) = cos\frac{\theta}{2}I - i sin\frac{\theta}{2}\sigma_Z = \begin{bmatrix} 1 & 0 \\ 0 & e^{i\theta} \end{bmatrix} \end{aligned}\end{split}\]

易证:

\[\begin{split}\begin{aligned} \begin{split} RX(\theta_X)RZ(\theta_Z) = RZ(\theta_Z)R_{-\theta_Z}(\theta_X) \\ RZ(\theta_{Z2})RZ(\theta_{Z1}) = RZ(\theta_{Z1} + \theta_{Z2}) \\ CZ[RZ(\theta_{Z1}) \otimes RZ(\theta_{Z2})] = [RZ(\theta_{Z1}) \otimes RZ(\theta_{Z2}) ]·CZ \end{split} \end{aligned}\end{split}\]

以上公式是Virtual Z 门的基础。它意味着,可以将线路中已有的Z操作转移到XY操作之后,作为替代,原XY操作的旋转轴将随之变换。而被转移到线路后排的Z操作可以合并,并继续转移,以此类推。

多比特量子逻辑门

量子计算机的空间随着量子比特的数量呈指数增长。对于 n 个量子比特,复向量空间的维数为 \(d=2^n\) 。为了描述多量子比特系统的状态,张量积被用来 "粘合 "算子和基向量。

让我们先考虑一个双量子比特系统。给定两个分别作用于一个量子比特的算子 A 和 B,那么作用于两个量子比特的联合算子 \(A\otimes B\) .

\[\begin{split}\begin{aligned} A\otimes B=\begin{pmatrix}A_{00}\begin{pmatrix}B_{00}&B_{01}\\B_{10}&B_{11}\end{pmatrix}&A_{01}\begin{pmatrix}B_{00}&B_{01}\\B_{10}&B_{11}\end{pmatrix}\\A_{10}\begin{pmatrix}B_{00}&B_{01}\\B_{10}&B_{11}\end{pmatrix}&A_{11}\begin{pmatrix}B_{00}&B_{01}\\B_{10}&B_{11}\end{pmatrix}\end{pmatrix} \end{aligned}\end{split}\]

其中, \(A_{jk} 和 B_{lm}\) 分别是A和B的矩阵元素。

与此类似,双量子比特系统的基向量也是通过单量子比特基向量的张量乘积形成的:

\[\begin{split}\begin{aligned} |00\rangle=\begin{pmatrix}1\begin{pmatrix}1\\0\end{pmatrix}\\0\begin{pmatrix}1\\0\end{pmatrix}\end{pmatrix}=\begin{pmatrix}1\\0\\0\\0\end{pmatrix}\quad|01\rangle=\begin{pmatrix}1\begin{pmatrix}0\\1\end{pmatrix}\\0\begin{pmatrix}0\\1\end{pmatrix}\end{pmatrix}=\begin{pmatrix}0\\1\\0\\0\end{pmatrix} \end{aligned}\end{split}\]
\[\begin{split}\begin{aligned} |10\rangle=\begin{pmatrix}0\begin{pmatrix}1\\0\end{pmatrix}\\1\begin{pmatrix}1\\0\end{pmatrix}\end{pmatrix}=\begin{pmatrix}0\\0\\1\\0\end{pmatrix}\quad|11\rangle=\begin{pmatrix}0\begin{pmatrix}0\\1\end{pmatrix}\\1\begin{pmatrix}0\\1\end{pmatrix}\end{pmatrix}=\begin{pmatrix}0\\0\\0\\1\end{pmatrix} \end{aligned}\end{split}\]

注意,我们为基向量的张量乘引入了一个简写 \(|0\rangle\otimes|0\rangle\) 记作 \(\left|00\right\rangle\) 。n 量子比特系统的状态可以用n维量子比特基向量的张量积来描述。请注意,2量子比特系统的基向量是4维的;如前所述,一般来说,n量子比特系统的基向量是 \(2^n\) 维的。

大多数双量子比特门都属于受控类型(SWAP 门是个例外)。一般来说,受控双量子比特门 \(C_U\) 的作用是,当第一个量子比特的状态处于 \(|1\rangle\) 时,将单量子比特单元应用于第二个量子比特U。假设有一个矩阵U表示

\[\begin{split}\begin{aligned} U=\begin{pmatrix}u_{00}&u_{01}\\u_{10}&u_{11}\end{pmatrix}. \end{aligned}\end{split}\]

我们可以计算出 \(C_U\) 的作用如下。回顾一下,双量子比特系统的基向量排序为 \(|00\rangle,|01\rangle,|10\rangle,|11\rangle\) 。假设控制量子比特是量子比特 \(q_0\) 。如果控制量子比特是 \(|1\rangle\) 的情况下,U则应作用于目标位。因此,在 \(C_U\) 的作用下,基向量会根据以下公式进行变换

\[\begin{aligned} C_{U}: \underset{\text{qubit}~1}{\left|0\right\rangle}\otimes \underset{\text{qubit}~0}{\left|0\right\rangle} &\rightarrow \underset{\text{qubit}~1}{\left|0\right\rangle}\otimes \underset{\text{qubit}~0}{\left|0\right\rangle} \end{aligned}\]
\[\begin{aligned} C_{U}: \underset{\text{qubit}~1}{\left|0\right\rangle}\otimes \underset{\text{qubit}~0}{\left|1\right\rangle} &\rightarrow \underset{\text{qubit}~1}{\left|0\right\rangle}\otimes \underset{\text{qubit}~0}{\left|1\right\rangle} \end{aligned}\]
\[\begin{aligned} C_{U}: \underset{\text{qubit}~1}{\left|1\right\rangle}\otimes \underset{\text{qubit}~0}{\left|0\right\rangle} &\rightarrow \underset{\text{qubit}~1}{\left|1\right\rangle}\otimes \underset{\text{qubit}~0}{U\left|0\right\rangle} \end{aligned}\]
\[\begin{aligned} C_{U}: \underset{\text{qubit}~1}{\left|1\right\rangle}\otimes \underset{\text{qubit}~0}{\left|1\right\rangle} &\rightarrow \underset{\text{qubit}~1}{\left|1\right\rangle}\otimes \underset{\text{qubit}~0}{U\left|1\right\rangle} \end{aligned}\]

\(C_U\) 的矩阵形式为:

\[\begin{split}\begin{aligned} \begin{aligned} C_U = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & u_{00} & u_{01} \\ 0 & 0 & u_{10} & u_{11} \end{pmatrix} \end{aligned} \end{aligned}\end{split}\]

其中,右下角对应酉矩阵形式为上述U4门:

CU
CU
\(\begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & u_{00} & u_{01} \\ 0 & 0 & u_{10} & u_{11} \end{bmatrix}\quad\)

CNOT门

作用于两个量子比特的量子门,当第一个量子比特(控制位)为 |1⟩的时候,对第二个量子比特施加一个X门的效果。 所以CNOT在很多文献中也称为CX门。

CNOT
CNOT
\(\begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \end{bmatrix}\quad\)

CZ门

如果控制量子比特是 |1⟩的时候,受控 Z 门会翻转目标量子比特的相位。无论控制量子位是 MSB 还是 LSB,矩阵看起来都是一样的:

\[\begin{split}\begin{aligned} C_Z = \begin{pmatrix} 1 & 0 & 0 & 0\\ 0 & 1 & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & -1 \end{pmatrix} \end{aligned}\end{split}\]
CZ
CZ
\(\begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & -1 \end{bmatrix}\quad\)

SWAP门

SWAP 门交换两个量子比特。它将基向量变换为

\[\begin{aligned} \left|00\right\rangle \rightarrow \left|00\right\rangle~,~\left|01\right\rangle \rightarrow \left|10\right\rangle~,~\left|10\right\rangle \rightarrow \left|01\right\rangle~,~\left|11\right\rangle \rightarrow \left|11\right\rangle \end{aligned}\]
SWAP
SWAP
\(\begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}\quad\)

受控相位旋转CR门

如果两个量子比特都处于 \(\left|11\right\rangle\) 状态,则进行相位旋转。无论控制比特是 MSB 还是 LSB,矩阵看起来都是一样的。

CR
CR
\(\begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & e^{i\theta} \end{bmatrix}\quad\)

iSWAP
iSWAP
\(\begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & i & 0 \\ 0 & i & 0 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}\quad\)
RXX
RXX
\(\begin{bmatrix} \cos(\theta/2) & 0 & 0 & -i\sin(\theta/2) \\ 0 & \cos(\theta/2) & -i\sin(\theta/2) & 0 \\ 0 & -i\sin(\theta/2) & \cos(\theta/2) & 0 \\ -i\sin(\theta/2) & 0 & 0 & \cos(\theta/2) \end{bmatrix}\quad\)
RYY
RYY
\(\begin{bmatrix} \cos(\theta/2) & 0 & 0 & i\sin(\theta/2) \\ 0 & \cos(\theta/2) & -i\sin(\theta/2) & 0 \\ 0 & -i\sin(\theta/2) & \cos(\theta/2) & 0 \\ i\sin(\theta/2) & 0 & 0 & \cos(\theta/2) \end{bmatrix}\quad\)
RZZ
RZZ
\(\begin{bmatrix} e^{-i\theta/2} & 0 & 0 & 0 \\ 0 & e^{i\theta/2} & 0 & 0 \\ 0 & 0 & e^{i\theta/2} & 0 \\ 0 & 0 & 0 & e^{-i\theta/2} \end{bmatrix}\quad\)
RZX
RZX
\(\begin{bmatrix} \cos(\theta/2) & 0 & -i\sin(\theta/2) & 0 \\ 0 & \cos(\theta/2) & 0 & i\sin(\theta/2) \\ -i\sin(\theta/2) & 0 & \cos(\theta/2) & 0 \\ 0 & i\sin(\theta/2) & 0 & \cos(\theta/2) \end{bmatrix}\quad\)

Toffoli门

如果前两个量子位都是 \(\left|1\right\rangle\) ,托福利门就会翻转第三个量子位。

\[\begin{aligned} |abc\rangle\to|bc\oplus a\rangle\otimes|b\rangle\otimes|c\rangle. \end{aligned}\]
Toffoli
Toffoli
\(\begin{bmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \\ \end{bmatrix}\quad\)

QPanda 2把所有的量子逻辑门封装为API向用户提供使用,并可获得QGate类型的返回值。比如,您想要使用Hadamard门,就可以通过如下方式获得:

from pyqpanda import *
import numpy as np
qvm = CPUQVM()
qvm.init_qvm()
qubits = qvm.qAlloc_many(4)
h = H(qubits[0])

其中参数为目标比特,返回值为量子逻辑门

pyqpanda中支持的不含角度的单门有: IHTSXYZX1Y1Z1

qubit如何申请会在 GPU量子虚拟机 部分介绍。

单门带有一个旋转角的逻辑门,例如RX门:

rx = RX(qubits[0], np.pi/3)

第一个参数为目标比特,第二个参数为旋转角度

pyqpanda中支持的单门带有一个旋转角度的逻辑门有: RXRYRZU1P

pyqpanda中还支持 U2U3U4 门,其用法如下:

# U2(qubit, phi, lambda) 有两个角度
u2 = U2(qubits[0], np.pi, np.pi/2)

# U3(qubit, theta, phi, lambda) 有三个角度
u3 = U3(qubits[0], np.pi, np.pi/2, np.pi/4)

# U4(qubit, alpha, beta, gamma, delta) 有四个角度
u4 = U4(qubits[0], np.pi, np.pi/2, np.pi/4, np.pi/2)

两比特量子逻辑门的使用和单比特量子逻辑门的用法相似,只不过是输入的参数不同,例如CNOT门:

cnot = CNOT(qubits[0], qubits[1])

第一个参数为控制比特 第二个参数为目标比特 注:两个比特不能相同

pyqpanda中支持的双门不含角度的逻辑门有: CNOTCZSWAPiSWApSqiSWAP

双门带有旋转角度的门有:CRRXXRYYRZZRZX,例如CR门:

cr = CR(qubits[0], qubits[1], np.pi)

第一个参数为控制比特, 第二个参数为目标比特, 第三个参数为旋转角度

支持CU门,使用方法如下:

# CU(control, target, alpha, beta, gamma, delta) 有四个角度
cu = CU(qubits[0], qubits[1], np.pi, np.pi/2, np.pi/3, np.pi/4)

获得三量子逻辑门 Toffoli 的方式:

toffoli = Toffoli(qubits[0], qubits[1], qubits[2])

三比特量子逻辑门Toffoli实际上是CCNOT门,前两个参数是控制比特,最后一个参数是目标比特。

接口介绍

在本章的开头介绍过,所有的量子逻辑门都是酉矩阵,那么您也可以对量子逻辑门做转置共轭操作,获得一个量子逻辑门 dagger 之后的量子逻辑门可以用下面的方法:

rx_dagger = RX(qubits[0], np.pi).dagger()

或:

rx_dagger = RX(qubits[0], np.pi)
rx_dagger.set_dagger(True)

也可以为量子逻辑门添加控制比特,获得一个量子逻辑门 control 之后的量子逻辑门可以用下面的方法:

qvec = [qubits[0], qubits[1]]
rx_control = RX(qubits[2], np.pi).control(qvec)

或:

qvec = [qubits[0], qubits[1]]
rx_control = RX(qubits[2], np.pi)
rx_control.set_control(qvec)

pyqpanda 还封装了一些比较方便的接口,会简化一些量子逻辑门的操作。

单门操作:

cir = H(qubits)
print(cir)
          ┌─┐
q_0:  |0>─┤H
          ├─┤
q_1:  |0>─┤H
          ├─┤
q_2:  |0>─┤H
          ├─┤
q_3:  |0>─┤H
          └─┘

对多个量子比特添加H门

双门操作:

cir = CNOT(qubits[0:3], qubits[1:4])
print(cir)
q_0:  |0>────■── ────── ──────
          ┌──┴─┐
q_1:  |0>─┤CNOT ───■── ──────
          └────┘ ┌──┴─┐
q_2:  |0>─────── CNOT ───■──
                 └────┘ ┌──┴─┐
q_3:  |0>─────── ────── CNOT
                        └────┘

对多个量子比特添加CNOT门

pyqpanda 还封装了自定义的QOracle逻辑门,通过传入一个由酉矩阵和对应的比特来构建一个QOracle逻辑门。

from pyqpanda import *

if __name__ == "__main__":
    qvm = CPUQVM()
    qvm.init_qvm()
    qubits = qvm.qAlloc_many(3)
    prog1 = QProg()
    prog1 <<H(qubits[0]) <<CNOT(qubits[1],qubits[2])
    mat = get_matrix(prog1,True)
    prog = QProg()
    prog << QOracle([qubits[0],qubits[1],qubits[2]],mat)

    res1 = qvm.prob_run_dict(prog1,qubits)
    res2 = qvm.prob_run_dict(prog,qubits)

    # 打印测量结果
    print(res1)
    print(res2)

计算结果如下:

{'000': 0.5000000000000001, '001': 0.5000000000000001, '010': 0.0, '011': 0.0, '100': 0.0, '101': 0.0, '110': 0.0, '111': 0.0}
{'000': 0.4999999999999999, '001': 0.4999999999999999, '010': 0.0, '011': 0.0, '100': 0.0, '101': 0.0, '110': 0.0, '111': 0.0}

实例

以下实例主要是向您展现QGate类型接口的使用方式。

from pyqpanda import *

if __name__ == "__main__":
   qvm = CPUQVM()
   qvm.init_qvm()
   qubits = qvm.qAlloc_many(3)
   control_qubits = [qubits[0], qubits[1]]
   prog = QProg()

   # 构建量子程序
   prog << apply_QGate([qubits[0], qubits[1]], H) \
         << H(qubits[0]).dagger() \
         << X(qubits[2]).control(control_qubits)

   # 对量子程序进行概率测量
   result = qvm.prob_run_dict(prog, qubits, -1)

   # 打印测量结果
   print(result)

计算结果如下:

{'000': 0.4999999999999894, '001': 0.0, '010': 0.4999999999999894, '011': 0.0, '100': 0.0, '101': 0.0, '110': 0.0, '111': 0.0}

量子线路


量子线路是量子计算领域中的一种重要模型,用于描述和研究量子算法和量子计算机的运行过程。它是一种图形化的表示方法,用于展示量子比特之间的操作和相互作用,类似于经典计算中的电路图。

由于组成量子线路的每一个量子逻辑门都是一个 酉算子 ,所以整个量子线路整体也是一个大的酉算子。

量子线路的主要目的是模拟和探究量子计算过程,通过在量子比特上应用各种量子门操作(如Hadamard门、CNOT门等),以实现复杂的量子算法,一般来说,量子线路的结构大致如下图所示:

_images/qcircuit.png

根据上图以及《量子计算与量子信息》一书的内容,量子线路的结构组成主要包括:

  • 量子比特(Qubits) :量子线路的基本单元,与经典计算中的比特类似,但具有量子叠加和纠缠等量子特性。

  • 量子操作和量子门(Quantum Gates) :这些是对量子比特进行操作的基本元素,类似于经典计算中的逻辑门。量子门可以是单比特门(只作用于一个量子比特)或多比特门(作用于多个量子比特),常见的有Hadamard门、Pauli门、CNOT门等。

  • 时间线 :即连接量子操作的线,表示执行时序,同时量子线路中量子门的顺序和连接方式形成了一种拓扑结构,该结构决定了量子算法的运行流程。

class QCircuit

该类实现了用于构建和操作量子线路的方法,通过添加量子门和控制操作等来生成量子线路。

__init__()

创建一个空的量子线路。

__init__(arg0: NodeIter)

根据给定的节点迭代器创建量子线路。

参数:

arg0 (NodeIter) -- 节点迭代器。

control(control_qubits: QVec) QCircuit

获得QCircuit的施加控制之后的量子线路

参数:

control_qubits (QVec) -- 控制比特列表。

返回:

新的施加控制后的量子线路。

返回类型:

QCircuit

dagger() QCircuit

获得QCircuit的转置共轭之后的量子线路

返回:

QCircuit的转置共轭之后的量子线路

返回类型:

QCircuit

insert(arg0: QCircuit) QCircuit
:: insert(arg0: QGate) -> QCircuit
参数:

arg0 (QGate、QCircuit) -- 要插入的量子门和量子线路。

返回:

当前量子线路。

返回类型:

QCircuit

is_empty() bool

检查量子线路是否为空。

返回:

若量子线路为空则为 True,否则为 False。

返回类型:

bool

set_control(control_qubits: QVec) None

设置控制比特,用于实现控制门操作。

参数:

control_qubits (QVec) -- 控制比特列表。

set_dagger(arg0: bool) None

设置线路是否为dagger形式。

参数:

arg0 (bool) -- 若为 True 则表示将线路设置为dagger

__lshift__(arg0: QCircuit) QCircuit
:: __lshift__(arg0: QGate) -> QCircuit
参数:

arg0 (QGate、QCircuit) -- 通过左移操作符待插入的节点

返回:

生成的新量子线路。

返回类型:

QCircuit

在pyqpanda中,QCircuit类是一个仅装载量子逻辑门的容器类型,它也是QNode中的一种,初始化一个QCircuit对象除了上述直接使用初始化函数外,

cir = QCircuit()

还可以使用

prog = create_empty_qcircuit()

你可以通过如下方式向QCircuit尾部填充节点,在这里pyqpanda重载了 << 运算符作为插入量子线路的方法

cir << node

node的类型可以为QGate或QCircuit。

我们还可以获得QCircuit的转置共轭之后的量子线路,使用方式为:

cir_dagger = cir.dagger()

如果想复制当前的量子线路,并给复制的量子线路添加控制比特,可以使用下面的方式:

qvec = [qubits[0], qubits[1]]
cir_control = cir.control(qvec)

备注

  • 向QCircuit中插入QPorg,QIf,Measure不会报错,但是运行过程中可能会产生预料之外的错误

  • 一个构建好的QCircuit不能直接参与量子计算与模拟,需要进一步构建成QProg类型

from pyqpanda import *

if __name__ == "__main__":

    qvm = CPUQVM()
    qvm.init_qvm()
    qubits = qvm.qAlloc_many(4)
    cbits = qvm.cAlloc_many(4)

    # 构建量子程序
    prog = QProg()
    circuit = QCircuit()

    circuit << H(qubits[0]) \
            << CNOT(qubits[0], qubits[1]) \
            << CNOT(qubits[1], qubits[2]) \
            << CNOT(qubits[2], qubits[3])

    prog << circuit << Measure(qubits[0], cbits[0])

    # 量子程序运行1000次,并返回测量结果
    result = qvm.run_with_configuration(prog, cbits, 1000)

    # 打印量子态在量子程序多次运行结果中出现的次数
    print(result)

运行结果:

{'0000': 486, '0001': 514}

通过对申请的寄存器中中添加量子门,来设计量子线路,下图是通过添加H门和CNOT门来实现GHZ态。

在qubit0上添加H门,使其变成叠加态 \(\left(|0\rangle+|1\rangle\right)/\sqrt{2}\)

在qubit0和qubit1,2,3之间分别添加一个CNOT门,在理想的量子计算机上,构成的线路运行之后产生的状态就是GHZ态。

_images/GHZ.png
\[\begin{aligned} |\psi\rangle = \left(|0000\rangle+|1111\rangle\right)/\sqrt{2} \end{aligned}\]
\[\begin{aligned} \left(|0\rangle+|1\rangle\right)/\sqrt{2} \end{aligned}\]
from pyqpanda import *

if __name__ == "__main__":

    qvm = CPUQVM()
    qvm.init_qvm()
    qubits = qvm.qAlloc_many(4)
    cbits = qvm.cAlloc_many(4)

    # 构建量子程序
    prog = QProg()

    measure_node = Measure(qubit, cbit)

    

    measure_node = Measure(0, 1)

量子程序


量子程序是一种描述量子计算任务的指令序列,类似于经典计算中的计算机程序。然而,与经典计算不同的是,量子程序在量子比特上执行操作,利用量子力学的奇特性质来进行信息处理。

在传统计算中,经典比特(0和1)是计算的基本单位,而在量子计算中,量子比特(或称为量子位)可以同时处于0和1的叠加态,还可以通过纠缠现象与其他量子比特相互关联。这些量子特性赋予了量子程序强大的计算能力,使其能够解决一些经典计算难题,如因子分解和优化问题。

量子程序的核心是量子门操作,它们是对量子比特进行操作的基本构建块。通过使用不同的量子门操作,可以在量子比特之间创建复杂的量子态和量子纠缠,实现量子计算中的各种算法和任务。量子程序还包括测量操作,将量子信息转化为经典信息以便进一步分析和处理。

编写和优化量子程序是量子计算研究和应用的关键一步。设计合理的量子门序列、选择适当的量子比特布局以及优化操作顺序等都会影响量子程序的执行效率和准确性。随着量子计算技术的不断发展,量子程序成为了探索量子算法、量子模拟、量子优化等领域的重要工具。

在QPanda2中,QProg是量子编程的一个容器类,是一个量子程序的最高单位。

class QProg

该类实现了量子程序的构建,使用链表数据结构存储量子电路。可用于构建量子电路,执行量子操作以及进行分析。

__init__()

初始化一个空的量子程序。

__init__(prog: QProg)

使用另一个量子程序构造新的量子程序节点。

参数:

prog (QProg) -- 要复制的量子程序。

返回:

一个新的量子程序节点。

__init__(qcircuit: QCircuit)

使用一个量子线路构造新的量子程序节点。

参数:

qcircuit (QCircuit) -- 要转换为量子程序的量子线路。

返回:

一个新的量子程序节点。

__init__(qif_prog: QIfProg)

使用一个 QIfProg 节点构造新的量子程序节点。

参数:

qif_prog (QIfProg) -- 要转换为量子程序的 QIfProg 节点。

返回:

一个新的量子程序节点。

__init__(qwhile_prog: QWhileProg)

使用一个 QWhileProg 节点构造新的量子程序节点。

参数:

qwhile_prog (QWhileProg) -- 要转换为量子程序的 QWhileProg 节点。

返回:

一个新的量子程序节点。

__init__(qgate: QGate)

使用一个 QGate 节点构造新的量子程序节点。

参数:

qgate (QGate) -- 要转换为量子程序的 QGate 节点。

返回:

一个新的量子程序节点。

__init__(qmeasure: QMeasure)

使用一个 QMeasure 节点构造新的量子程序节点。

参数:

qmeasure (QMeasure) -- 要转换为量子程序的 QMeasure 节点。

返回:

一个新的量子程序节点。

__init__(qreset: QReset)

使用一个 QReset 节点构造新的量子程序节点。

参数:

qreset (QReset) -- 要转换为量子程序的 QReset 节点。

返回:

一个新的量子程序节点。

__init__(cc: ClassicalCondition)

使用一个 ClassicalCondition 节点构造新的量子程序节点。

参数:

cc (ClassicalCondition) -- 要转换为量子程序的 ClassicalCondition 节点。

返回:

一个新的量子程序节点。

__init__(node_iter: NodeIter)

使用一个 NodeIter 节点构造新的量子程序节点。

参数:

node_iter (NodeIter) -- 要转换为量子程序的 NodeIter 节点。

返回:

一个新的量子程序节点。

get_max_qubit_addr()

获取量子程序中最大的量子比特地址,下标从0开始

get_qgate_num()

获取量子程序中的量子门数量。

get_used_cbits(cbit_vector: List[ClassicalCondition]) List[ClassicalCondition]

获取量子程序中使用的经典比特列表。

参数:

cbit_vector (List[ClassicalCondition]) -- 用于存储使用的经典比特的列表。

返回:

使用的经典比特列表。

返回类型:

List[ClassicalCondition]

get_used_qubits(qubit_vector: QVec) QVec

获取量子程序中使用的量子比特列表。

参数:

qubit_vector (QVec) -- 用于存储使用的量子比特的列表。

返回:

使用的量子比特列表。

返回类型:

QVec

insert(node: QProg | QGate | QCircuit | QIfProg | QWhileProg | QMeasure | QReset | ClassicalCondition) QProg

在量子程序中插入一个节点。

参数:

node (Union[QProg, QGate, QCircuit, QIfProg, QWhileProg, QMeasure, QReset, ClassicalCondition]) -- 要插入的节点。

返回:

修改后的量子程序。

返回类型:

QProg

is_empty()

判断量子程序是否为空。

is_measure_last_pos()

判断量子程序最后一个节点是否为测量操作。

last()

获取量子程序的最后一个节点。

__lshift__(node: QProg | QGate | QCircuit | QIfProg | QWhileProg | QMeasure | QReset | ClassicalCondition) QProg

通过左移操作符在量子程序中插入一个节点。

参数:

node (Union[QProg, QGate, QCircuit, QIfProg, QWhileProg, QMeasure, QReset, ClassicalCondition]) -- 要插入的节点。

返回:

修改后的量子程序。

返回类型:

QProg

它也是QNode中的一种,初始化一个QProg对象也可以使用下面的方式

prog = create_empty_qprog()

还可以由已有的QNode节点来构建量子程序,如:

qubit = qAlloc()

gate = H(qubit)

prog = QProg(gate)

可以用类似的方式构建量子程序的有QCircuit、QGate、QWhileProg、QIfProg、ClassicalCondition、QMeasure。

你可以通过如下方式向QProg尾部填充节点, 在这里pyqpanda重载了 << 运算符作为插入量子线路的方法

prog << node

QNode的类型有QGate,QPorg,QIf,Measure等等,QProg支持插入所有类型的QNode

QProg还支持 cast_qprog_qcircuit 接口,可以将QProg转换成QCircuit类型:

cir = cast_qprog_qcircuit(prog)
print(cir)

QProg还支持 cast_qprog_qgate 接口,可以将QProg转换成QGate类型:

gate = cast_qprog_qgate(prog)

QProg还支持 cast_qprog_qmeasure 接口,可以将QProg转换成QMeasure类型:

qmeas = cast_qprog_qmeasure(prog)

from pyqpanda import *

if __name__ == "__main__":

    qvm = CPUQVM()
    qvm.init_qvm()
    qubits = qvm.qAlloc_many(4)
    cbits = qvm.cAlloc_many(4)
    prog = QProg()

    # 构建量子程序
    prog << H(qubits[0]) \
         << X(qubits[1]) \
         << iSWAP(qubits[0], qubits[1]) \
         << CNOT(qubits[1], qubits[2]) \
         << H(qubits[3]) \
         << measure_all(qubits, cbits)

    # 量子程序运行1000次,并返回测量结果
    result = qvm.run_with_configuration(prog, cbits, 1000)

    # 打印量子态在量子程序多次运行结果中出现的次数
    print(result)

运行结果:

{'0001': 232, '0111': 263, '1001': 243, '1111': 262}

QProg支持 get_all_used_qubits 接口,可以获取到QProg中所有已使用到的比特信息:

used_qv = get_all_used_qubits(prog)

量子测量

量子测量是量子力学中的基本概念之一,用于引入外界的干扰获取量子系统的信息。在量子计算中,量子测量是评估量子比特状态的一种方式,它对量子信息的提取和观测起着至关重要的作用。

在量子计算中,测量通常被建模为对量子比特的一种操作,该操作将一个或多个量子比特的状态映射到经典的位(0或1)上。测量的结果是随机的,遵循一定的概率分布,这与量子力学的本质相关。

测量操作可以通过一系列测量门来实现,这些门用于将量子比特状态映射到经典位。蒙特卡洛方法在量子测量中的应用是指使用随机数模拟量子测量的随机性。在蒙特卡洛方法中,我们可以随机生成一组数值,这些数值代表测量结果的概率分布。通过模拟大量的测量,我们可以得到相应的统计数据,从而逼近真实的量子测量结果。

需要注意的是,量子测量会破坏量子系统的纯态,使其坍缩到一个确定的经典状态上。这个过程被称为量子态的“坍缩”或“投影”,而坍缩后的状态是测量结果所对应的状态。

在量子线路中用如下图标表示:

_images/QGate_measure.png

接口介绍

本章主要介绍获得量子测量对象、根据配置运行含有量子测量的量子程序、快速测量。

在量子程序中我们需要对某个量子比特做测量操作,并把测量结果存储到经典寄存器上,可以通过下面的方式获得一个测量对象:

Measure(qubit: Qubit | int, cbit: ClassicalCondition | CBit) QMeasure

此函数用于创建一个量子测量节点,用于测量给定的量子比特,并将测量结果存储在指定的经典比特中。

参数:
  • qubit (Union[Qubit, int]) -- 要测量的量子比特。可以是量子比特对象或量子比特的索引。

  • cbit (Union[ClassicalCondition, CBit]) -- 存储量子测量结果的经典比特。可以是经典比特对象或经典比特的索引。

返回:

一个量子测量节点,表示测量操作。

返回类型:

QMeasure

如果想测量所有的量子比特并将其存储到对应的经典寄存器上,可以使用 measure_all

measure_all(qubit_list: QVec | List[int], cbit_list: List[ClassicalCondition]) QProg

创建一组量子测量节点

此函数用于创建一组量子测量节点,用于同时测量给定的多个量子比特,并将测量结果分别存储在对应的经典比特中。

param qubit_list:

要测量的量子比特列表。可以是量子比特对象列表或量子比特的索引列表。

type qubit_list:

Union[QVec, List[int]]

param cbit_list:

存储量子测量结果的经典比特列表。

type cbit_list:

List[ClassicalCondition]

return:

一个量子程序,包含一组量子测量节点,表示同时对多个量子比特进行测量。

rtype:

QProg

备注

measure_all 的返回值类型是 QProg

在得到含有量子测量的程序后,我们可以调用 directly_runrun_with_configuration 来得到量子程序的测量结果。

  1. 直接运行量子程序并返回运行的结果 :directly_run

directly_run(self, qprog: QProg, noise_model: Noise = NoiseModel()) Dict[str, bool]

该方法用于直接运行量子程序,无需预先初始化。在使用此方法之前,请确保已进行初始化(init)操作。

参数:
  • qprog (QProg) -- 要运行的量子程序。

  • noise_model (Noise, optional) -- 噪声模型,默认为无噪声模型。噪声模型目前仅在 CPUQVM 上生效。

返回:

量子程序执行结果的字典,包含两个键值对。第一个键为最终量子比特寄存器状态,第二个键为其测量概率。

返回类型:

Dict[str, bool]

示例用法:

from pyqpanda import *
qvm = CPUQVM()
qvm.init_qvm()
qubits = qvm.qAlloc_many(4)
cbits = qvm.cAlloc_many(4)

prog = QProg()
prog << H(qubits[0])\
     << CNOT(qubits[0], qubits[1])\
     << CNOT(qubits[1], qubits[2])\
     << CNOT(qubits[2], qubits[3])\
     << Measure(qubits[0], cbits[0])

result = qvm.directly_run(prog)
  1. 统计量子程序多次运行的测量结果 : run_with_configuration

run_with_configuration(self, qprog: QProg, cbit_list: List[ClassicalCondition] | List[int], data: dict, noise_model: Noise = NoiseModel()) Dict[str, int]

此函数用于以配置信息运行量子程序,并返回在不同运行次数下的执行结果。

参数:
  • qprog (QProg) -- 要运行的量子程序。

  • cbit_list (Union[List[ClassicalCondition], List[int]]) -- 存储测量结果的经典比特列表或经典比特索引列表。

  • data (dict) -- 配置信息,用于不同运行次数的设置。

  • noise_model (Noise, optional) -- 噪声模型,用于模拟噪声影响。默认为无噪声模型。

返回:

在不同运行次数下的执行结果。结果以字典形式返回,键为量子态的二进制字符串表示,值为对应的命中次数。

返回类型:

Dict[str, int]

run_with_configuration(self, qprog: QProg, shot: int, noise_model: Noise = NoiseModel()) Dict[str, int]

此函数用于以配置信息运行量子程序,并返回在指定运行次数下的执行结果。

参数:
  • qprog (QProg) -- 要运行的量子程序。

  • shot (int) -- 运行次数。

  • noise_model (Noise, optional) -- 噪声模型,用于模拟噪声影响。默认为无噪声模型。

返回:

在指定运行次数下的执行结果。结果以字典形式返回,键为量子态的二进制字符串表示,值为对应的命中次数。

返回类型:

Dict[str, int]

示例用法:

from pyqpanda import *
prog = QProg()
prog << H(qubits[0])\
     << H(qubits[0])\
     << H(qubits[1])\
     << H(qubits[2])\
     << measure_all(qubits, cbits)
result = run_with_configuration(prog, 1000)

实例

from pyqpanda import *

if __name__ == "__main__":
    qvm = CPUQVM()
    qvm.init_qvm()
    qubits = qvm.qAlloc_many(4)
    cbits = qvm.cAlloc_many(4)

    # 构建量子程序
    prog = QProg()
    prog << H(qubits[0])\
         << H(qubits[1])\
         << H(qubits[2])\
         << H(qubits[3])\
         << measure_all(qubits, cbits)

    # 量子程序运行1000次,并返回测量结果
    result = qvm.run_with_configuration(prog, cbits, 1000)

    # 打印测量结果
    print(result)

运行结果:

{'0000': 59, '0001': 69, '0010': 52, '0011': 62,
'0100': 63, '0101': 67, '0110': 79, '0111': 47,
'1000': 73, '1001': 59, '1010': 72, '1011': 60,
'1100': 61, '1101': 71, '1110': 50, '1111': 56}

QIf

QIf表示量子程序条件判断操作,输入参数为条件判断表达式,功能是执行条件判断。

在量子计算中,除了对量子比特进行操作外,还可以根据经典寄存器的状态来执行条件操作。这意味着我们可以根据经典寄存器中存储的经典信息来决定是否执行特定的量子操作。

这种条件操作使得量子计算能够根据经典信息灵活地调整量子门的应用,从而实现更加复杂和多样化的计算过程。

例如,假设我们有一个经典寄存器中存储了一个位的值,可以是0或1。我们可以根据这个位的值来决定是否对量子比特应用某个特定的量子门操作。如果经典寄存器中的位是0,我们执行一系列操作;如果位是1,我们执行另一系列操作。通过这种方式,我们可以在量子计算中引入经典信息,从而实现更加智能和可控的计算过程。

在量子计算中,经典寄存器是与量子比特(qubit)相对应的一个概念。

由于量子计算和经典计算是不同的计算模型,它们之间需要有适当的接口来实现数据的传递和交互。经典寄存器就是这种接口之一,用于在量子计算和经典计算之间传递信息。

经典寄存器是一个类似于经典计算机中的比特(bit)的概念,它代表了一个经典的二进制值(0或1)。

在量子计算中,经典寄存器用于记录量子计算的结果。当量子计算完成后,量子比特的测量结果将被存储在经典寄存器中,以供后续的经典计算和分析使用。

在一些量子计算算法和量子门操作中,可能需要基于经典信息来控制量子操作,即 QIf、QWhile 操作等,经典寄存器可以用于记录这些控制信息,从而实现更复杂的量子计算任务。

class ClassicalCondition

经典寄存器类

__init__(*args, **kwargs)

初始化 ClassicalCondition 类实例。

get_val() int

获取经典条件的值。

返回:

经典条件的值。

返回类型:

int

set_val(value: int) None

设置经典条件的值。

参数:

value (int) -- 要设置的经典条件的值。

返回:

无返回值。

__add__(other: ClassicalCondition | int) ClassicalCondition

重载操作符 +,用于经典条件的加法运算。

参数:

other (Union[ClassicalCondition, int]) -- 要进行加法运算的另一个经典条件或整数。

返回:

计算结果作为新的经典条件。

返回类型:

ClassicalCondition

__eq__(other: ClassicalCondition | int) ClassicalCondition

重载操作符 ==,用于经典条件的等于比较。

参数:

other (Union[ClassicalCondition, int]) -- 要进行等于比较的另一个经典条件或整数。

返回:

计算结果作为新的经典条件。

返回类型:

ClassicalCondition

__ge__(other: ClassicalCondition | int) ClassicalCondition

重载操作符 >=,用于经典条件的大于等于比较。

参数:

other (Union[ClassicalCondition, int]) -- 要进行大于等于比较的另一个经典条件或整数。

返回:

计算结果作为新的经典条件。

返回类型:

ClassicalCondition

__gt__(other: ClassicalCondition | int) ClassicalCondition

重载操作符 >,用于经典条件的大于比较。

参数:

other (Union[ClassicalCondition, int]) -- 要进行大于比较的另一个经典条件或整数。

返回:

计算结果作为新的经典条件。

返回类型:

ClassicalCondition

__le__(other: ClassicalCondition | int) ClassicalCondition

重载操作符 <=,用于经典条件的小于等于比较。

参数:

other (Union[ClassicalCondition, int]) -- 要进行小于等于比较的另一个经典条件或整数。

返回:

计算结果作为新的经典条件。

返回类型:

ClassicalCondition

__lt__(other: ClassicalCondition | int) ClassicalCondition

重载操作符 <,用于经典条件的小于比较。

参数:

other (Union[ClassicalCondition, int]) -- 要进行小于比较的另一个经典条件或整数。

返回:

计算结果作为新的经典条件。

返回类型:

ClassicalCondition

__mul__(other: ClassicalCondition | int) ClassicalCondition

重载操作符 *,用于经典条件的乘法运算。

参数:

other (Union[ClassicalCondition, int]) -- 要进行乘法运算的另一个经典条件或整数。

返回:

计算结果作为新的经典条件。

返回类型:

ClassicalCondition

__radd__(other: int) ClassicalCondition

重载操作符 +,用于右侧加法运算。

参数:

other (int) -- 要进行加法运算的整数。

返回:

计算结果作为新的经典条件。

返回类型:

ClassicalCondition

__rmul__(other: int) ClassicalCondition

重载操作符 *,用于右侧乘法运算。

参数:

other (int) -- 要进行乘法运算的整数。

返回:

计算结果作为新的经典条件。

返回类型:

ClassicalCondition

__rsub__(other: int) ClassicalCondition

重载操作符 -,用于右侧减法运算。

参数:

other (int) -- 要进行减法运算的整数。

返回:

计算结果作为新的经典条件。

返回类型:

ClassicalCondition

__rtruediv__(other: int) ClassicalCondition

重载操作符 /,用于右侧除法运算。

参数:

other (int) -- 要进行除法运算的整数。

返回:

计算结果作为新的经典条件。

返回类型:

ClassicalCondition

__sub__(other: ClassicalCondition | int) ClassicalCondition

重载操作符 -,用于经典条件的减法运算。

参数:

other (Union[ClassicalCondition, int]) -- 要进行减法运算的另一个经典条件或整数。

返回:

计算结果作为新的经典条件。

返回类型:

ClassicalCondition

__truediv__(other: ClassicalCondition | int) ClassicalCondition

重载操作符 /,用于经典条件的除法运算。

参数:

other (Union[ClassicalCondition, int]) -- 要进行除法运算的另一个经典条件或整数。

返回:

计算结果作为新的经典条件

c_and(arg0: ClassicalCondition | int) ClassicalCondition

执行与其他经典条件或整数的逻辑与操作。

参数:

arg0 (Union[ClassicalCondition, int]) -- 用于逻辑与操作的其他经典条件或整数。

返回:

作为新的经典条件的与操作结果。

返回类型:

ClassicalCondition

c_not() ClassicalCondition

执行逻辑非操作。

返回:

作为新的经典条件的非操作结果。

返回类型:

ClassicalCondition

c_or(arg0: ClassicalCondition | int) ClassicalCondition

执行与其他经典条件或整数的逻辑或操作。

参数:

arg0 (Union[ClassicalCondition, int]) -- 用于逻辑或操作的其他经典条件或整数。

返回:

作为新的经典条件的或操作结果。

返回类型:

ClassicalCondition

在QPanda2中,QIfProg类用于表示执行量子程序条件判断操作,它也是QNode中的一种,QIf的定义如下:

class QIfProg

表示量子条件分支的类,有两种初始化方式。

__init__(self, arg0: NodeIter) None

创建一个量子条件分支节点。

参数:

arg0 (NodeIter) -- 分支节点的迭代器。

返回:

无返回值

返回类型:

None

创建一个具有指定迭代器的量子条件分支节点。

__init__(self, classical_cond: ClassicalCondition, true_branch_qprog: QProg) None

创建一个量子条件分支节点,具有一个正确分支的情况。

参数:
  • classical_cond (ClassicalCondition) -- 用于判断是否执行正确分支的经典条件。

  • true_branch_qprog (QProg) -- 正确分支的量子线路。

返回:

无返回值

返回类型:

None

创建一个具有给定经典条件和正确分支量子线路的量子条件分支节点。

__init__(self, classical_cond: ClassicalCondition, true_branch_qprog: QProg, false_branch_qprog: QProg) None

创建一个量子条件分支节点,具有正确分支和错误分支的情况。

参数:
  • classical_cond (ClassicalCondition) -- 用于判断是否执行正确分支的经典条件。

  • true_branch_qprog (QProg) -- 正确分支的量子线路。

  • false_branch_qprog (QProg) -- 错误分支的量子线路。

返回:

无返回值

返回类型:

None

创建一个具有给定经典条件、正确分支量子线路和错误分支量子线路的量子QIf节点。

get_classical_condition(self) ClassicalCondition

获取该量子条件分支节点的经典条件。

返回:

经典条件

返回类型:

ClassicalCondition

get_false_branch(self) QProg

获取该量子条件分支节点的错误分支量子线路。

返回:

错误分支量子线路

返回类型:

QProg

get_true_branch(self) QProg

获取该量子条件分支节点的正确分支量子线路。

返回:

正确分支量子线路

返回类型:

QProg

可以传入的QNode类型有: QProg、QCircuit、QGate、QWhileProg、QIfProg、QMeasure。

from pyqpanda import *

if __name__ == "__main__":

    qvm = CPUQVM()
    qvm.init_qvm()
    qubits = qvm.qAlloc_many(3)
    cbits = qvm.cAlloc_many(3)
    cbits[0].set_val(0)
    cbits[1].set_val(3)

    prog = QProg()
    branch_true = QProg()
    branch_false = QProg()

    # 构建QIf正确分支以及错误分支
    branch_true << H(qubits[0])<< H(qubits[1]) << H(qubits[2])
    branch_false << H(qubits[0]) << CNOT(qubits[0], qubits[1]) << CNOT(qubits[1], qubits[2])

    # 构建QIf
    qif = QIfProg(cbits[0] > cbits[1], branch_true, branch_false)

    # QIf插入到量子程序中
    prog << qif

    # 概率测量,并返回目标量子比特的概率测量结果,下标为十进制
    result = qvm.prob_run_tuple_list(prog, qubits, -1)

    # 打印概率测量结果
    print(result)

运行结果:

[(0, 0.4999999999999999), (7, 0.4999999999999999), (1, 0.0), (2, 0.0), (3, 0.0), (4, 0.0), (5, 0.0), (6, 0.0)]

经典寄存器可以同时实现一些经典的判断表达式或者逻辑语句,例如经典逻辑中的and和or,代码示例如下:

from pyqpanda import *
import binascii

if __name__ == "__main__":
    qvm = CPUQVM();
    qvm.init_qvm();
    qubits = qvm.qAlloc_many(3);
    cbits = qvm.cAlloc_many(6);

    test_prog = QProg();
    test_prog << H(qubits[0]) \
        << CNOT(qubits[0], qubits[1]) \
        << H(qubits[2]) \
        << Measure(qubits[0], cbits[0])\
        << Measure(qubits[1], cbits[1])\
        << Measure(qubits[2], cbits[2]) \
        << Measure(qubits[0], cbits[3])\
        << Measure(qubits[1], cbits[4])\
        << Measure(qubits[2], cbits[5])

    result_test = qvm.run_with_configuration(test_prog, cbits, 1000);
    print(result_test)

    p = QProg();
    p << H(qubits[0]) \
        << CNOT(qubits[0], qubits[1]) \
        << H(qubits[2]) \
        << Measure(qubits[0], cbits[0])\
        << Measure(qubits[1], cbits[1])\
        << Measure(qubits[2], cbits[2])

    true_prog1 = QProg();
    true_prog2 = QProg();
    true_prog3 = QProg();
    true_prog4 = QProg();

    true_prog3 << X(qubits[2]);

    if_prog3 = create_if_prog((cbits[0] == 0).c_and(cbits[1] == 0).c_and(cbits[2] == 0), true_prog3)

    p << if_prog3
    p << Measure(qubits[0], cbits[3])\
        << Measure(qubits[1], cbits[4])\
        << Measure(qubits[2], cbits[5])

    result = qvm.run_with_configuration(p, cbits, 1000)
    print(result)

运行结果:

{'000000': 257, '011011': 259, '100100': 237, '111111': 247}
{'011011': 251, '100000': 220, '100100': 263, '111111': 266}

QWhile


无论是经典计算还是量子计算领域中,循环结构在许多算法和应用中扮演着重要角色。

量子QWhile循环节点是一种在量子程序中实现循环结构的机制,使得我们能够基于经典条件来重复执行一系列量子操作。这一概念类似于传统编程语言中的while循环,但在量子计算中涉及了量子比特和量子门操作。

实现量子While循环的常见方法是通过一个经典控制条件来判断循环是否继续,当然也可以是量子经典寄存器,一个典型的使用案例是利用量子QWhile循环节点来实现迭代优化算法,在这种情况下,经典条件可以是一组优化参数的变化是否达到收敛,而循环体中的量子操作可以是执行某种量子优化步骤。通过不断重复这个循环,我们可以逐步优化量子态或量子门操作,以实现更精确的结果。

在QPanda2中,QWhileProg类用于表示执行量子程序while循环操作,它也是QNode中的一种,QWhileProg的定义如下:

class QWhileProg

量子 While 循环节点用于在量子程序中实现循环结构,允许基于经典条件重复执行量子操作。

__init__(self, arg0: NodeIter) None

创建一个 Quantum While 循环节点。

参数:

arg0 (NodeIter) -- 循环中的量子操作的迭代器。

返回:

无返回值

返回类型:

None

该构造函数创建一个 Quantum While 循环节点,其中循环体是由迭代器中的量子操作构成。在每次循环迭代中,将执行迭代器中的量子操作。

__init__(self, arg0: ClassicalCondition, arg1: QProg) None

创建一个 Quantum While 循环节点。

参数:
返回:

无返回值

返回类型:

None

该构造函数创建一个 Quantum While 循环节点,其中循环体是由参数中的量子操作构成。循环将根据经典条件判断是否继续执行循环体中的操作。

get_classical_condition(self) ClassicalCondition

获取循环的经典条件。

返回:

循环的经典条件。

返回类型:

ClassicalCondition

该方法返回用于控制循环执行的经典条件,该条件将在每次循环迭代前进行判断。

get_true_branch(self) QProg

获取循环体中的量子操作。

返回:

循环体中的量子操作。

返回类型:

QProg

该方法返回在循环体中定义的量子操作,这些操作将在每次循环迭代中执行。

可以传入的QNode类型有: QProg、QCircuit、QGate、QWhileProg、QIfProg、QMeasure。

关于经典寄存器可以参考 经典寄存器

from pyqpanda import *

if __name__ == "__main__":

    qvm = CPUQVM()
    qvm.init_qvm()
    qubits = qvm.qAlloc_many(3)
    cbits = qvm.cAlloc_many(3)
    cbits[0].set_val(0)
    cbits[1].set_val(1)

    prog = QProg()
    prog_while = QProg()

    # 构建QWhile的循环分支
    prog_while << H(qubits[0]) << H(qubits[1])<< H(qubits[2])\
            << assign(cbits[0], cbits[0] + 1) << Measure(qubits[1], cbits[1])

    # 构建QWhile
    qwhile = QWhileProg(cbits[1], prog_while)

    # QWhile插入到量子程序中
    prog << qwhile

    # 运行,并打印测量结果
    result = qvm.directly_run(prog)
    print(result)
    print(cbits[0].get_val())

运行结果:

{'c1': False}
0

量子程序统计

量子程序统计

在量子算法的设计以及量子计算机的性能分析中,经常需要对外界计算参数——量子程序进行分析,了解量子程序的结构信息对于优化和调试量子算法至关重要。

为了帮助研究者和开发者更方便地获取量子程序的结构信息,我们提供了一个便捷的接口 count_prog_info ,用于统计量子程序的节点数和层数

通过使用这个接口,可以快速了解量子程序的总节点数、总层数以及各类型节点和层的数量,为进一步的研究和优化提供有力支持,以及同时提供简单的可视化接口

当涉及到量子程序的层数(Layer)时,我们实际上在描述量子门(Quantum Gate)的分层排列方式。层数是用来表示量子程序中各个量子门在时间轴上的位置关系,从而更好地理解量子计算过程的组织和流程。

在量子计算中,每一层代表了一组同时执行的量子门操作,这些操作可以并行地在量子计算机的不同量子比特上进行。在某一层内,所有的量子门操作都是同时发生的,而不同层之间的操作可以顺序执行。通过合理地分层和排列,我们可以最大限度地利用量子计算机的并行性,提高量子算法的效率。

考虑下面的例子:

_images/layer_test.png

在这个例子中,第一层的三个H门可以同时执行,上图中一共可以划分为7层,我们可以采用不同的优化策略和编译算法来最小化层数,从而优化量子程序的执行效率和减少量子比特的错误率。

总之,量子程序的层数是对量子门操作在时间上排列的一种描述,用于指导量子计算的顺序执行。理解层数的概念对于优化和调试量子程序非常重要。

pyqpanda中可以使用 count_prog_info 对层数和节点数进行统计。

class ProgCount

该类用于统计量子程序的信息,包括双比特门层数、双比特门数量、单比特门数量、多控制门数量、总量子门数量、层数、节点数量等。

double_gate_layer_num

纯双比特门的层数。

double_gate_num

双比特门的数量。

gate_num

总门的数量。

layer_num

量子线路的层数。

node_num

节点的数量。

single_gate_layer_num

纯单比特门的层数。

single_gate_num

单比特门的数量。

multi_control_gate_num

多控制门的数量。

selected_gate_nums

选取特定量子门的数量

__init__()

初始化 ProgCount 类实例。

count_prog_info(node: QProg, select_gate_types: [] = None) ProgCount

该函数用于统计给定量子程序的信息,包括门层数、门数量等。

参数:

node (QProg or QCircuit) -- 要统计信息的量子程序。

返回:

ProgCount 结构,包含统计信息。

返回类型:

ProgCount

注意:函数支持两种重载方式,分别接受 QProg 和 QCircuit 类型的量子程序作为参数,可以选择指定要统计的量子逻辑门数量合集

示例用法:

# 统计 QProg 的信息
prog_info = count_prog_info(my_qprog)

# 统计 QCircuit 的信息,并启用优化
optimized_info = count_prog_info(my_qcircuit ,[pq.GateType.HADAMARD_GATE])

# 获取统计结果的各种属性
num_layers = prog_info.layer_num
num_gates = prog_info.gate_num
num_double_gates = prog_info.double_gate_num
# ... 其他属性获取

具体示例可参考下面的程序:

import pyqpanda as pq
import matplotlib.pyplot as plt

machine = pq.CPUQVM()
machine.init_qvm()

q = machine.qAlloc_many(6)
c = machine.cAlloc_many(6)

prog = pq.QProg()
prog << pq.hadamard_circuit(q) << pq.QFT(q) << pq.QFT(q) << pq.measure_all(q,c)

prog_info = pq.count_prog_info(prog,[pq.GateType.HADAMARD_GATE])

#总节点数,包括逻辑门,测量和reset等
print("all nodes num : ",prog_info.node_num)

#总逻辑门数量
print("all gate num : ",prog_info.gate_num)

#总层数
print("all layer num : ",prog_info.layer_num)

#总的单门数量
print("single gate num : ",prog_info.single_gate_num)

#总的双门数量
print("double gate num : ",prog_info.double_gate_num)

#纯单门构成的层数
print("single gate layer num : ",prog_info.single_gate_layer_num)

#纯双门构成的层数
print("double gate layer num : ",prog_info.double_gate_layer_num)

#筛选的量子逻辑门数量
print("selected_gate_nums : ",prog_info.selected_gate_nums)

#可视化接口
pq.show_prog_info_count(prog)

运行结果如下:

all nodes num :  60
all gate num :  54
all layer num :  26
single gate num :  18
double gate num :  36
single gate layer num :  3
double gate layer num :  11
selected_gate_nums :  {<GateType.HADAMARD_GATE: 10>: 18}
_images/count_layer.png

量子程序时钟周期

量子程序时钟周期用于在已知每个量子逻辑门在运行时所需时间的条件下,估算一个量子程序运行所需要的时间。

每个量子逻辑门的时间设置在项目的元数据配置文件 QPandaConfig.xml 中, 如果未设置则会给定一个默认值,单量子门的默认时间为1,双量子门的时间为2。

"QGate": {
    "SingleGate":{
        "U3":{"time":1}
    },
    "DoubleGate":{
        "CNOT":{"time":2},
        "CZ":{"time":2}
    }
}

具体时间根据每一层中运行时间最长的量子操作依次累加得到的时间,以下图为例,我们可以一共划分为 4

_images/count_time.png

最终的时钟周期数为每一层的时间累加。

接口介绍

get_qprog_clock_cycle(qprog: QProg, machine: QuantumMachine, optimize: bool = False) int

该函数用于计算给定量子程序在指定量子机器上运行所需的时钟周期数,可以选择是否进行优化来获取不同条件下的时钟周期数。

参数:
  • qprog (QProg) -- 要计算时钟周期的量子程序。

  • machine (QuantumMachine) -- 执行量子程序的量子机器。

  • optimize (bool, optional) -- 是否对量子程序进行优化。默认为 False,为True时需要提供配置文件

返回:

量子程序运行所需的时钟周期数,没有单位,不以秒为单位。

返回类型:

int

示例用法:

cycle_count = get_qprog_clock_cycle(my_qprog, my_machine, optimize=True)

备注

时钟周期数是一个与具体硬件和实现有关的相对量,不具备实际物理单位。

参见

QProg, QuantumMachine

我们先用pyQPanda构建一个量子程序:

prog = QProg()
prog << H(qubits[0]) << CNOT(qubits[0], qubits[1])\
     << iSWAP(qubits[1], qubits[2]) << RX(qubits[3], np.pi / 4)

然后调用 get_qprog_clock_cycle 接口得到量子程序的时钟周期

clock_cycle = get_qprog_clock_cycle(qvm, prog)

实例

from pyqpanda import *
import numpy as np

if __name__ == "__main__":
    qvm = CPUQVM()
    qvm.init_qvm()
    qubits = qvm.qAlloc_many(4)
    cbits = qvm.cAlloc_many(4)

    # 构建量子程序
    prog = QProg()
    prog << H(qubits[0]) << CNOT(qubits[0], qubits[1])\
         << iSWAP(qubits[1], qubits[2]) << RX(qubits[3], np.pi / 4)

    # 统计量子程序时钟周期
    clock_cycle = get_qprog_clock_cycle(prog, qvm)

    print(clock_cycle)

运行结果:

5

量子线路可视化

量子线路可视化是一个用于呈现和分析量子电路的工具,它在量子计算和量子信息领域扮演着重要角色。

量子线路可视化的主要目的是通过图形化表示来理解和研究量子电路。通过直观的图像,可以更清楚地看到量子比特之间的相互作用、量子门的顺序以及量子算法的结构。

根据常用的使用场景,可视化输出主要分为 控制台终端打印输出为图片 等两大部分。

在控制台输出中,我们使用文本字符来模拟量子比特和量子门操作。 每个量子比特通常用一个小方框或者是一个字母来表示,而量子门操作则以其代表的操作名称缩写来表示,比如用"H"表示Hadamard门,用"CNOT"表示控制非门等。

量子比特之间的连接关系通过使用空格、竖线和斜线等特殊字符,例如,如果一个量子门操作作用在两个量子比特之间,我们可以在这两个量子比特之间画一条连线来表示它们之间的相互作用。这样可以清楚地看到量子比特之间是如何通过量子门进行信息交换和相互影响的。

pyqpanda中可以直接通过 printdraw_qprog 来输出和保存量子线路可视化结果

draw_qprog(prog, output=None, scale=0.7, filename=None, with_logo=False, line_length=100, NodeIter_first=None, NodeIter_second=None, console_encode_type='utf8')

draw_qprog提供了一个便捷的方式将量子线路以多种不同的视觉格式呈现,通过控制台格式化输出或保存量子线路函数,具体有以下功能

  • 文本形式 :通过使用文本图案,在控制台中显示量子线路的结构和操作序列。这种呈现方式适用于快速的调试和查看,能够以简洁的方式展示量子比特之间的连接关系和操作顺序。

  • 图像形式 :将量子线路绘制成图像,提供了更丰富的视觉信息。用户可以选择不同的图像输出格式,如PNG或SVG,以适应不同的用途。图像展示适合用于演示、教学和文档编写,可以突出量子比特之间的连接关系、量子门操作的分布以及线路的整体结构。

  • LaTeX源代码形式 :将量子线路转换为LaTeX源代码,使用户能够方便地将量子线路嵌入到LaTeX文档中。这对于学术论文、技术报告和课件制作非常有用。用户可以在文档中无缝地插入量子线路图,与其他数学和物理公式相结合,从而形成一体化的呈现方式。

参数:
  • prog (QuantumCircuit) -- 要绘制的量子线路。

  • output (str, optional) -- 指定绘制的输出格式,可选值为 "text"、"pic" 或 "latex"。默认为 None。

  • scale (float, optional) -- 绘制图像的缩放比例(如果小于1则缩小),仅在“pic”输出格式下使用。默认为 0.7。

  • filename (str, optional) -- 保存图像的文件路径,默认为 None。

  • with_logo (bool, optional) -- 是否在图像中包含标识,仅在“pic”输出格式下使用。默认为 False。

  • NodeIter_first (int, optional) -- 电路绘制的起始位置。默认为 None。

  • NodeIter_second (int, optional) -- 电路绘制的结束位置。默认为 None。

  • console_encode_type (str, optional) -- 目标控制台编码类型,支持 'utf8' 和 'gbk',仅在“pic”输出格式下使用。默认为 'utf8'。

  • line_length (int, optional) -- 设置“text”输出类型生成的行长度。默认为 100。

返回:

无返回值。

返回类型:

None

示例:

from numpy import pi
from pyqpanda import *
from pyqpanda.Visualization import circuit_draw

machine = CPUQVM()
machine.init_qvm()

qlist = machine.qAlloc_many(4)
clist = machine.cAlloc_many(4)

measure_prog = QProg()
measure_prog << hadamard_circuit(qlist) \
<< CZ(qlist[1], qlist[2]) \
<< RX(qlist[2], pi / 4) \
<< RX(qlist[1], pi / 4) \
<< CNOT(qlist[0], qlist[2]) \
<< Measure(qlist[0], clist[0])

print(measure_prog)

对于上面的一段量子程序,可以直接通过 print 输出到控制台

# 通过print直接输出量子线路字符画,该方法会在控制台输出量子线路,输出格式为utf8编码,所以在非utf8编码的控制台下,输出字符画会出现乱码情况。
# 同时,该方法会将当前量子线路字符画信息保存到文件,文件名为 “QCircuitTextPic.txt”,文件用utf8编码,并保存在当面路径下面,
# 所以用户也可以通过该文件查看量子线路信息,注意该文件要以uft8格式打开,否则会出现乱码。
print(measure_prog)

输出结果如下:

对于需要保存为图片的使用场景,可以使用 draw_qprog

draw_qprog(measure_prog, 'pic', filename='D:/test_cir_draw.png')

输出的量子线路图片效果如下:

密度矩阵

对于一些低量子比特系统而言,能够展示整个系统的量子态分布、密度矩阵分布或者Bloch轨迹,对于算法研究有很大帮助。 pyqpanda提供了类似的功能接口。

对于量子态,可以通过 state_to_density_matrix 转化为密度矩阵,参数是 量子态数组 ,可以参考如下示例。

state_to_density_matrix(quantum_state)

该函数用于将量子态转换为密度矩阵。

参数:

quantum_state (list of complex numbers) -- 要转换的量子态,以复数列表形式表示。

返回:

密度矩阵。

返回类型:

numpy.ndarray

抛出:

RuntimeError -- 如果输入不是有效的量子态。

一个简单的例子:

from pyqpanda import *
import numpy as np

machine = CPUQVM()
machine.init_qvm()
qubits = machine.qAlloc_many(3)

prog = QProg()
prog << X(qubits[0:2])\
    << Z(qubits[:2])\
    << H(qubits[:])

machine.directly_run(prog)
state = machine.get_qstate()
density_matrix = state_to_density_matrix(state)
print(density_matrix)

输出结果如下:

[[ 0.125+0.j -0.125-0.j -0.125-0.j  0.125+0.j  0.125+0.j -0.125-0.j
-0.125-0.j  0.125+0.j]
[-0.125+0.j  0.125+0.j  0.125+0.j -0.125+0.j -0.125+0.j  0.125+0.j
0.125+0.j -0.125+0.j]
[-0.125+0.j  0.125+0.j  0.125+0.j -0.125+0.j -0.125+0.j  0.125+0.j
0.125+0.j -0.125+0.j]
[ 0.125+0.j -0.125-0.j -0.125-0.j  0.125+0.j  0.125+0.j -0.125-0.j
-0.125-0.j  0.125+0.j]
[ 0.125+0.j -0.125-0.j -0.125-0.j  0.125+0.j  0.125+0.j -0.125-0.j
-0.125-0.j  0.125+0.j]
[-0.125+0.j  0.125+0.j  0.125+0.j -0.125+0.j -0.125+0.j  0.125+0.j
0.125+0.j -0.125+0.j]
[-0.125+0.j  0.125+0.j  0.125+0.j -0.125+0.j -0.125+0.j  0.125+0.j
0.125+0.j -0.125+0.j]
[ 0.125+0.j -0.125-0.j -0.125-0.j  0.125+0.j  0.125+0.j -0.125-0.j
-0.125-0.j  0.125+0.j]]

量子态分布

如果需要打印量子态的分布,可以使用 plot_state_city 接口,函数定义如下

plot_state_city(quantum_state, title='', figsize=None, color=None, ax_real=None, ax_imag=None)

该函数用于绘制量子态的立体分布图。

参数:
  • quantum_state (list of complex) -- 要绘制城市图的量子态,应为复数列表。

  • title (str, optional) -- 图的标题,默认为空字符串。

  • figsize (tuple, optional) -- 图的尺寸,格式为 (宽度, 高度),默认为 None。

  • color (str, optional) -- 图的颜色设置,默认为 None。

  • ax_real (matplotlib.axes.Axes, optional) -- 用于绘制实部的 Matplotlib 坐标轴,默认为 None。

  • ax_imag (matplotlib.axes.Axes, optional) -- 用于绘制虚部的 Matplotlib 坐标轴,默认为 None。

返回:

Matplotlib 图形对象。

返回类型:

matplotlib.figure.Figure

使用示例:

from pyqpanda import *
import numpy as np

machine = CPUQVM()
machine.set_configure(50, 50)
machine.init_qvm()
q = machine.qAlloc_many(4)
c = machine.cAlloc_many(4)
prog = QProg()
prog.insert(X(q[1]))\
    .insert(T(q[0]))\
    .insert(RX(q[1], np.pi/2))\
    .insert(RZ(q[0], np.pi/4))
machine.directly_run(prog)
result = machine.get_qstate()
plot_state_city(result)
machine.finalize()

终端会通过matplot绘制具体的量子态分布如下

_images/plot_state_city.png

对于密度矩阵,我们可以通过 plot_density_matrix 来打印密度矩阵,函数定义如下:

plot_density_matrix(M, xlabels=None, ylabels=None, title=None, limits=None, phase_limits=None, fig=None, axis_vals=None, threshold=None)

该函数用于绘制给定量子态的密度矩阵图像,以直观地呈现量子态的结构和性质。

参数:
  • M (list of complex) -- 要绘制的量子态的复数列表(密度矩阵)。密度矩阵是量子力学中描述量子态的矩阵表示,包含了量子态的全部信息。

  • xlabels (list, optional) -- 用于自定义X轴标签的列表。每个标签对应密度矩阵的一列。默认为 None。

  • ylabels (list, optional) -- 用于自定义Y轴标签的列表。每个标签对应密度矩阵的一行。默认为 None。

  • title (str, optional) -- 图像的标题,用于指明图像的主题或特定含义。默认为 None。

  • limits (tuple, optional) -- 图像的显示范围,可控制颜色的映射范围。默认为 None。

  • phase_limits (tuple, optional) -- 相位的显示范围,用于调整相位颜色的映射范围。默认为 None。

  • fig (matplotlib.figure.Figure, optional) -- Matplotlib图像对象,用于在现有图像上绘制。默认为 None。

  • axis_vals (list, optional) -- 自定义轴的值,用于更改轴上的刻度值。默认为 None。

  • threshold (float, optional) -- 阈值,用于控制在图像中隐藏低于此值的元素。默认为 None。

返回:

Matplotlib图像对象,呈现了量子态的密度矩阵图像。

返回类型:

matplotlib.figure.Figure

使用示例:

from pyqpanda import *
import numpy as np

machine = CPUQVM()
machine.set_configure(50, 50)
machine.init_qvm()
q = machine.qAlloc_many(4)
c = machine.cAlloc_many(4)
prog = QProg()
prog.insert(X(q[1]))\
    .insert(H(q[0]))\
    .insert(H(q[1]))\
    .insert(T(q[2]))\
    .insert(RX(q[1], np.pi/2))\
    .insert(RY(q[3], np.pi/3))\
    .insert(RZ(q[0], np.pi/4))\
    .insert(RZ(q[1], np.pi))\
    .insert(RZ(q[2], np.pi))\
    .insert(RZ(q[3], np.pi))
machine.directly_run(prog)
result = machine.get_qstate()
rho = state_to_density_matrix(result)
plot_density_matrix(rho)
machine.finalize()

终端会通过matplot绘制具体的密度矩阵分布如下:

_images/state_to_density_matrix.png

Bloch球轨迹

对于单个比特而言,有些情况下我们需要研究它的Bloch球运动轨迹,这个功能可以通过 plot_bloch_circuit 接口,函数定义如下:

plot_bloch_circuit(circuit, trace=True, saveas=None, fps=20, secs_per_gate=1)

该函数用于绘制一个量子线路的 Bloch 球视图,仅支持单量子比特。

参数:
  • circuit (QuantumCircuit) -- 要绘制的量子线路。

  • trace (bool, optional) -- 是否显示 Bloch 球轨迹。默认为 True。

  • saveas (str, optional) -- 保存图像的文件路径。默认为 None。

  • fps (int, optional) -- 动画的帧率。默认为 20。

  • secs_per_gate (int, optional) -- 每个门操作的显示时间(秒)。默认为 1。

返回:

Bloch 球视图的图像。

返回类型:

Figure

使用代码示例:

from pyqpanda import *
import numpy as np

machine = CPUQVM()
machine.set_configure(50, 50)
machine.init_qvm()
q = machine.qAlloc_many(2)
c = machine.cAlloc_many(2)
cir = QCircuit()
cir.insert(RX(q[0], np.pi/2)) \
    .insert(RZ(q[0], np.pi / 2)) \
    .insert(RZ(q[0], np.pi/6))\
    .insert(RY(q[0], np.pi/3))\
    .insert(RX(q[0], np.pi/9))
plot_bloch_circuit(cir)
machine.finalize()

终端会动态展示单个量子比特线路的Bloch轨迹如下:

_images/bolch_cir.jpg

概率分布

在运行一个量子线路得到概率分布后,可以通过 draw_probailitydraw_probaility_dict 绘制具体的概率分布, 他们的区别是第一个函数参数是dict类型,包含量子态二进制表示与对应的概率,另一个函数参数是list,表示量子态概率数组,运行示例如下:

draw_probability(probability_dict)

该函数用于绘制量子态概率分布的字典。

参数:

probability_dict (dict) -- 要绘制的量子态概率分布字典,其中键是量子态,值是概率值。

返回:

无返回值。

返回类型:

None

一个简单的例子如下:

from pyqpanda import *

machine = CPUQVM()
machine.init_qvm()
qubits = machine.qAlloc_many(3)

prog = QProg()
prog << Z(qubits[0])\
    << X1(qubits[1])\
    << H(qubits[:2])

machine.directly_run(prog)
result_dict = machine.prob_run_dict(prog, qubits, -1)
draw_probaility_dict(result_dict)
machine.finalize()

绘制的概率分布图如下:

_images/draw_probaility_dict.png

使用经典计算机模拟量子线路

量子模拟器是在量子计算领域中具有重要意义的工具,它们为研究人员和开发者提供了模拟和分析量子系统行为的有效手段。 这些工具不仅有助于理解量子算法和量子系统的特性,还能够在实际的量子计算机尚未普及的情况下进行算法设计和验证。

在量子电路的模拟方法中,选择合适的模拟后端非常重要,不同量子线路模拟器的适用场所如下:

全振幅量子虚拟机 :全振幅模拟器可以同时模拟和存储量子态的全部振幅,但受限于机器的内存条件,量子比特达到50位已是极限,适合低比特高深度的量子线路,比如低比特下的谷歌随机量子线路以及需要获取全部模拟结果的场景等。

部分振幅量子虚拟机 :部分振幅模拟器依赖于其他模拟器提供的低比特量子线路振幅模拟结果,能模拟更高的比特数量,但能模拟的深度降低,通常用于获取量子态振幅的部分子集模拟结果。

单振幅量子虚拟机 :单振幅模拟器能模拟更高的量子比特线路图,同时模拟的性能较高,不会随着量子比特数目增加呈指数型增长,但随着线路深度增加,模拟性能急剧下降,同时难以模拟多控制门也是其缺点,该模拟器适用于高比特低深度的量子线路模拟,通常用于快速地模拟获得单个量子态振幅结果。

张量网络量子虚拟机 :张量网络模拟器与单振幅类似,与单振幅对比,可以模拟多控制门,同时在深度较高的线路模拟上存在性能优势。

量子云虚拟机 :量子云虚拟机可以将任务提交在远程高性能计算集群上运行,突破本地硬件性能限制,同时支持在真实的量子芯片上运行量子算法。

全振幅量子虚拟机

背景介绍

量子电路的经典模拟对于更好地理解量子计算的操作和行为是至关重要的。这样的模拟使研究人员和开发人员能够评估新量子算法的复杂性,并验证量子设备的有效性。

全振幅模拟是量子计算领域中最经典的模拟方案之一,用于模拟较小规模的量子系统。在这个模拟方案中,可以实现对整个量子系统的状态进行精确模拟,从而获得系统在不同时间点上的演化情况。这个方法的核心思想是表示和跟踪量子态的完整振幅信息,通过密度矩阵或纯态向量来描述量子系统的状态。

对于一个量子比特来说,可以看作是一个两能级系统,量子态 \(|\psi\rangle\) 可以表示为:

\[|\psi\rangle=a_0|0\rangle+a_1|1\rangle\]

其中 \(a_0\)\(a_1\) 是复振幅,并且:

\[\left|a_0\right|^2+\left|a_1\right|^2=1\]

式子中 \(|0\rangle\)\(|1\rangle\) 是两个计算标准正交基态,量子态也可以用如下方法表示

\[\begin{split}|\psi\rangle=a_0\left[\begin{array}{l} 1 \\ 0 \end{array}\right]+a_1\left[\begin{array}{l} 0 \\ 1 \end{array}\right]=\left[\begin{array}{l} a_0 \\ a_1 \end{array}\right]\end{split}\]

对于一个 n-比特量子系统来说,可以通过 \(2^n\) 个振幅来表示

\[|\psi\rangle=a_{0 . \ldots 00}|0 \ldots 00\rangle+a_{0 . \ldots 01}|0 \ldots 01\rangle+\ldots+a_{1 . \ldots 11}|1 \ldots 11\rangle\]

所有振幅满足概率归一化条件,即

\[\sum_i\left|a_i\right|^2=1\]

在量子计算过程中,所有的量子逻辑门可以通过矩阵形式施加到系统中。将单门U施加到第K个量子比特上的过程可以表述为:

\[A=I^{\otimes n-k-1} \otimes U \otimes I^{\otimes k},\]

其中I是 \(2 \times 2\) 的单位矩阵, U是 \(2 \times 2\) 酉矩阵,对于双门操作来说,这个过程是类似的。

可以看出,随着量子比特增加,需要表征的量子态振幅数量随指数增加,具体可以参考如下表,这一问题称为量子霸权。

模拟的量子比特数

全部量子态存储所需的最低内存/GB

26

1

27

1

28

4

29

8

30

16

...

...

48

\(2^{22}\)

49

\(2^{23}\)

50

\(2^{24}\)

当达到50比特及以上时,需要的内存数是一个天文数字,这个问题即所谓的 量子霸权(Quantum Supremacy) ,指量子计算机在某些特定任务上展现出超越经典计算机的能力,即在这些任务上实现了经典计算机无法模拟的优越性能。

这种现象突显了量子计算机在某些领域具有巨大的潜力,因为它们能够在短时间内解决一些经典计算机需要花费数年、数百年甚至更多时间才能解决的问题。

接口介绍

QPanda2中在构造量子虚拟机时有以下几种方式:

init(QMachineType.CPU)  # 使用init,不会返回qvm,会在代码中生成一个全局的qvm
auto qvm = init_quantum_machine(QMachineType.CPU) # 通过接口得到quantum machine对象
qvm = CPUQVM() # 新建一个quantum machine对象

备注

initinit_quantum_machine 这两个函数不是线程安全的,不适用于多线程编程,而且其最大的量子比特个数和经典寄存器个数均为默认值25。

设置好配置之后要初始化量子虚拟机:

qvm.init_qvm()

备注

调用 initinit_quantum_machine 接口, 就不需要初始化了。

全振幅虚拟机支持计算float与double精度的数据,设置方式如下:

qvm = CPUQVM()
#True: double精度, False: float精度
qvm.init_qvm(True)

下面我们就需要去申请量子比特和经典寄存器。

设置最大量子比特个数

# 设置最大量子比特个数和最大经典寄存器个数
qvm.set_configure(30, 30)

备注

若不设置则默认最大比特为29。

例如我们申请4个量子比特:

qubits = qvm.qAlloc_many(4)

申请一个量子比特时也可以用这个接口:

qubit = qvm.qAlloc()

申请经典寄存器也有类似于申请量子比特的接口,其使用方法和申请量子比特的方法一样,如申请4个经典寄存器的方法:

cbits = qvm.cAlloc_many(4)

申请一个经典寄存器时也可以用这个接口:

cbit = qvm.cAlloc()

在一个量子虚拟机中,申请了几次量子比特或经典寄存器,我们想知道一共申请了多少个量子比特或经典寄存器可以用下面的方法:

num_qubit = qvm.get_allocate_qubit_num() # 申请量子比特的个数
num_cbit = qvm.get_allocate_cmem_num() # 申请经典寄存器的个数

我们该如何使用量子虚拟机来执行量子程序呢? 可以用下面的方法:

prog = QProg()
prog << H(qubits[0]) << CNOT(qubits[0], qubits[1]) << Measure(qubits[0], cbits[0])

result = qvm.directly_run(prog) # 执行量子程序

如果想多次运行一个量子程序,并得到每次量子程序的结果,除了循环调用 directly_run 方法外, 我们还提供了一个接口 run_with_configuration ,该接口有两种重载方法,具体方法如下:

result = qvm.run_with_configuration(prog, cbits, shots)

一种方法中 prog 为量子程序, cbits 为 ClassicalCondition list, shots 是一个整型数据,为量子程序运行次数。

result = qvm.run_with_configuration(prog, cbits, config)

另一种方法中 prog 为量子程序, cbits 为 ClassicalCondition list, config 是一个字典类型的数据,内容如下:

config = {'shots': 1000}

如果想得到量子程序运行之后各个量子态的振幅值,可以调用 get_qstate 函数获得:

stat = qvm.get_qstate()

量子虚拟机中测量和概率使用方法与 量子测量概率测量 中介绍的相同,在这里就不多做赘述。

实例1

from pyqpanda import *

if __name__ == "__main__":
    qvm = CPUQVM()
    qvm.init_qvm()

    qvm.set_configure(29, 29)
    qubits = qvm.qAlloc_many(4)
    cbits = qvm.cAlloc_many(4)

    # 构建量子程序
    prog = QProg()
    prog << H(qubits[0]) << CNOT(qubits[0], qubits[1]) << Measure(qubits[0], cbits[0])

    # 量子程序运行1000次,并返回测量结果
    result = qvm.run_with_configuration(prog, cbits, 1000)

    # 打印量子态在量子程序多次运行结果中出现的次数
    print(result)
    qvm.finalize()

运行结果:

{'0000': 481, '0001': 519}

备注

这个量子程序的运行结果是不确定的,但其 00000001 对应的值都应该在500左右。

为了方便使用,pyqpanda还封装了一些面向过程的接口,接口名称和使用方法与上述的基本相同。我们将上面的例子修改为面向过程的接口如下:

实例2

from pyqpanda import *

if __name__ == "__main__":
    init(QMachineType.CPU)
    qubits = qAlloc_many(4)
    cbits = cAlloc_many(4)

    # 构建量子程序
    prog = QProg()
    prog << H(qubits[0]) << CNOT(qubits[0], qubits[1]) << Measure(qubits[0], cbits[0])

    # 量子程序运行1000次,并返回测量结果
    result = run_with_configuration(prog, cbits, 1000)

    # 打印量子态在量子程序多次运行结果中出现的次数
    print(result)
    finalize()

运行结果:

{'0000': 484, '0001': 516}

GPU量子虚拟机

背景介绍

GPU量子模拟器提供了另一种全振幅模拟方案,当涉及到计算密集型任务,如复杂的数学计算、图像处理和机器学习等,GPU的并行处理能力使其比CPU更高效,在量子计算的模拟中的优势体现在以下几点:

  1. 并行计算架构 :GPU并行处理能力源于其设计理念,将多个简单的处理器组合在一起,形成大规模的计算能力。这些处理器可以同时执行多个计算任务,从而在处理大规模数据实现高效的并行计算。而量子态的向量计算中,可以分成不同区块,这些区块之间可以并行。

  2. 任务分割和调度 :GPU在执行任务时,任务调度由GPU驱动程序负责,可以根据任务的需求动态分配处理单元和内存资源,当对大型量子线路模拟时,CPU通常需要预设计算资源分配和调度算法,而GPU可以直接交给GPU驱动程序自动调度。

  3. 高效的数据缓存和内存管理 :GPU具有高速的显存和缓存系统,有助于减少数据访问延迟,提高计算效率。此外,GPU还支持对内存进行多层次管理,以优化数据访问和存储。

  4. 高性能编程模型和算法 :为了方便开发者利用GPU的并行处理能力,GPU厂商提供了多种并行编程模型和工具,如CUDA、OpenCL等,量子计算模拟中的矩阵和线性计算任务能充分发挥性能优势。

接口介绍

class GPUQVM(QuantumMachine)

GPU模拟器类,该类实现了基于GPU计算平台的量子线路模拟。

__init__()

初始化 GPUQVM 类实例。

init_qvm() None

初始化量子虚拟机。

返回:

无返回值。

run_with_configuration(prog: QVec, shots : int, const NoiseModel& = NoiseModel()) Dict[str, int]

获取采样测量结果的字典形式。

参数:
  • qprog (QProg) -- 要运行的量子程序。

  • shots (int) -- 要采样测量的次数。

  • noise_model (Noise, optional) -- 噪声模型。默认为空的噪声模型。

返回:

包含测量结果的字典,键为测量结果的二进制字符串,值为对应的次数。

返回类型:

Dict[str, int]

抛出:

run_fail -- 获取测量结果失败。

prob_run_dict(program: QProg, qubit_list: QVec, select_max: int = -1) Dict[str, float]

运行量子程序并获取测量概率结果的字典形式。

参数:
  • program (QProg) -- 要运行的量子程序。

  • qubit_list (QVec) -- 用于测量的量子比特列表。

  • select_max (int, optional) -- 返回的元素数量上限。默认为 -1,表示无限制。

返回:

包含测量概率的字典,键为测量结果的二进制字符串,值为对应的测量概率。

返回类型:

Dict[str, float]

抛出:

run_fail -- 运行量子程序失败。

prob_run_list(program: QProg, qubit_list: QVec, select_max: int = -1) List[float]

运行量子程序并获取测量概率结果的列表形式。

参数:
  • program (QProg) -- 要运行的量子程序。

  • qubit_list (QVec) -- 用于测量的量子比特列表。

  • select_max (int, optional) -- 返回的元素数量上限。默认为 -1,表示无限制。

返回:

包含测量概率的列表。

返回类型:

List[float]

抛出:

run_fail -- 运行量子程序失败。

prob_run_tuple_list(program: QProg, qubit_list: QVec, select_max: int = -1) List[Tuple[int, float]]

运行量子程序并获取测量概率结果的元组列表形式。

参数:
  • program (QProg) -- 要运行的量子程序。

  • qubit_list (QVec) -- 用于测量的量子比特列表。

  • select_max (int, optional) -- 返回的元素数量上限。默认为 -1,表示无限制。

返回:

包含测量概率的元组列表,每个元组包含测量结果的索引和对应的概率。

返回类型:

List[Tuple[int, float]]

抛出:

run_fail -- 运行量子程序失败。

GPU模拟器的使用方法和CPUQVM类似,代码示例如下:

代码示例

from pyqpanda import *
from numpy import pi

if __name__ == "__main__":

    qvm = GPUQVM()
    qvm.init_qvm()

    qvm.set_configure(29, 29)
    q = qvm.qAlloc_many(4)
    c = qvm.cAlloc_many(4)

    # 构建量子程序
    prog = QProg()
    prog << H(q[0])\
            << CNOT(q[0], q[1])\
            << RZ(q[0], pi / 4)\
            << RX(q[2], pi / 4)\
            << CZ(q[0], q[1])\
            << CZ(q[2], q[3])

    measure_prog = QProg()
    measure_prog << prog\
                << Measure(q[0], c[0])\
                << Measure(q[1], c[1])

    # 量子程序运行1000次,并返回测量结果
    measure_result = qvm.run_with_configuration(measure_prog, 1000)

    prob_result = qvm.prob_run_dict(prog, [q[0],q[1]])

    # 打印量子态在量子程序多次运行结果中出现的次数
    print(measure_result)
    print(prob_result)
    qvm.finalize()

运行结果:

{'00': 497, '11': 503}
{'00': 0.5, '01': 0.0, '10': 0.0, '11': 0.5}

备注

使用GPU虚拟机需要本地运行环境有cuda环境

全振幅量子虚拟机噪声模拟

在真实的量子计算机中,受制于量子比特自身的物理特性,常常存在不可避免的计算误差。为了能在量子虚拟机中更好的模拟这种误差,在全振幅虚拟机中, 支持对噪声进行模拟,含噪声模拟的量子虚拟机更贴近真实的量子计算机。我们可以自定义噪声类型影响到的量子比特,自定义逻辑门支持的噪声模型, 通过这些自定义形式,我们使用QPanda2开发量子程序的现实应用程度将更高。

物理背景

纯态,混合态

量子计算中,量子比特使用态矢来表示,在没有噪声的理想状态下,量子比特在逻辑门的演化下一直处于纯态(pure state):

\[\begin{aligned} |\psi \rangle = |\varphi\rangle = \alpha|0\rangle + \beta|1\rangle \end{aligned}\]

当有噪声干扰时,系统会演化到混合态(mixed state)。混合态 \(|\psi\rangle\) 无法使用纯态的线性叠加来表示,通常用系综(ensemble)来表示:

\[\begin{split}\begin{aligned} \{|\varphi_1\rangle, |\varphi_2\rangle, ..., |\varphi_n\rangle\} \\ \{p_1, p_2, ..., p_n\} \end{aligned}\end{split}\]

系统 \(|\psi\rangle\) 的最终状态,以 \(p_1\) 的概率处于纯态 \(|\varphi_1\rangle = \alpha_1|0\rangle + \beta_1|1\rangle\) ,以 \(p_2\) 的概率处于纯态 \(|\varphi_2\rangle= \alpha_2|0\rangle + \beta_2|1\rangle\) ,以此类推。

混合态不是纯态的线性叠加。假设系统处于 \(\{|0\rangle, |1\rangle\},\{\frac{1}{2},\frac{1}{2}\}\) 的混合态, 那么系统最终的状态,50%的概率处于 \(|0\rangle\), 50%的概率处于 \(|1\rangle\)。 多次重复测量得到的结果与态 \(\frac{1}{\sqrt 2}|0\rangle + \frac{1}{\sqrt 2}|1\rangle\) 相同,但两者的量子态却完全不同。

噪声对系统的演化

量子计算机,作为一个孤立系统,不受外界干扰时,一直处于纯态。当外界噪音干扰与计算机比特耦合之后,计算机加上外界整个系统处于纯态。但对于计算机这个系统,则其处于混合态。

我们可以用一个简单的模型来等效演示

初始态两比特为 \(|\psi_{1}\psi_0\rangle\) ,其中,\(|\psi_0\rangle\) 代表我们的量子计算机系统, \(|\psi_1\rangle\) 表示外界。当外界对计算机无干扰时,\(|\psi_0\rangle\) 是个孤立系统,当逻辑门施加在 \(|\psi_0\rangle\) 上时,其始终为纯态。 如果模拟外界对量子计算机的干扰,将两个比特制备为纠缠态,即外界对计算机造成了噪声干扰。对于两个比特的整个系统来讲,仍然处于纯态。此时整个系统处于

\[|\psi_{1}\psi_0\rangle = \frac{1}{\sqrt{2}}|00\rangle+\frac{1}{{\sqrt{2}}}|11\rangle\]

但当只看0比特位时,即我们的量子计算机,其态矢不能从中分离出来,表示为纯态的线性叠加,\(|\psi_0\rangle\neq\frac{1}{\sqrt{2}}|0\rangle+\frac{1}{{\sqrt{2}}}|1\rangle\), 此时单独对于 \(|\psi_0\rangle\) 来讲,其已经处于混合态(由约化密度矩阵可知)。测量得到50%概率为 \(|0\rangle\), 50%的概率为 \(|1\rangle\)

噪声对包含计算机和环境的整个系统的演化算子是酉的,但仅对于计算机量子态的来看,则可能是非酉的。 因此,对于噪声对计算机系统量子态的演化,通常使用算子和表示(operator-sum representation):

\[\rho^{\prime} = \sum\limits_{i}{K_i}{\rho} {K_i}^{\dagger}\]

其中 \(K_i\) 为表示噪声演化的Kraus算子,满足

\[\sum\limits_{i}K_{i}^{\dagger} K_{i} = 1\]

噪声模型介绍

QPanda2为我们提供了丰富的噪声模型,我们可以自定义噪声模型和量子逻辑门的对应关系。噪声模型主要分为两种:单门噪声模型和双门噪声模型。

单门噪声模型

DAMPING_KRAUS_OPERATOR

DAMPING_KRAUS_OPERATOR是量子比特的弛豫过程噪声模型,它的kraus算符和表示方法如下所示:

\(K_1 = \begin{bmatrix} 1 & 0 \\ 0 & \sqrt{1 - p} \end{bmatrix}, K_2 = \begin{bmatrix} 0 & \sqrt{p} \\ 0 & 0 \end{bmatrix}\)

需要一个噪声参数 \(p\) ,为取值 \([0, 1]\) 之间的实数,意义为发生噪声影响的概率。

假设初始态处于 \(|\psi\rangle = \frac{1}{\sqrt 2}|0\rangle + \frac{1}{\sqrt 2}|1\rangle\) 使用算子和表示来演化噪声的影响:

\[\begin{split}\rho^{\prime} = K_1\rho K_{1}^{\dagger} + K_2\rho K_{2}^{\dagger} = \frac{1}{2} \begin{bmatrix} 1+p & \sqrt{1 - p}\\ \sqrt{1 - p} & 1 - p \end{bmatrix}\end{split}\]

测量得到结果的概率分别为:

\[\begin{split}\begin{aligned} p(|0\rangle) = \frac{1}{2}(1+p) \\ p(|1\rangle) = \frac{1}{2}(1-p) \end{aligned}\end{split}\]

\(tr(\rho^2) = \frac{1}{2}(2-p+p^2)\) 可见,当 \(p=0\)\(1\) 时,系统仍为纯态;当 \(p=(0, 1)\) 时,系统处于混合态。 可见,当 \(p\)\(0\) 时,即没有噪声影响,量子态保持不变;若 \(p\)\(1\) 时,必定发生弛豫,演化为态 \(|0\rangle\)

后面的噪声演化过程不再演示,读者可以自行演算。

DEPHASING_KRAUS_OPERATOR

DEPHASING_KRAUS_OPERATOR是量子比特的退相位过程噪声模型,它的kraus算符和表示方法如下所示:

\(K_1 = \begin{bmatrix} \sqrt{1 - p} & 0 \\ 0 & \sqrt{1 - p} \end{bmatrix}, K_2 = \begin{bmatrix} \sqrt{p} & 0 \\ 0 & -\sqrt{p} \end{bmatrix}\)

需要一个噪声参数。

DECOHERENCE_KRAUS_OPERATOR

DECOHERENCE_KRAUS_OPERATOR是退相干噪声模型,为上述两种噪声模型的综合,他们的关系如下所示:

\(P_{damping} = 1 - e^{-\frac{t_{gate}}{T_1}}, P_{dephasing} = 0.5 \times (1 - e^{-(\frac{t_{gate}}{T_2} - \frac{t_{gate}}{2T_1})})\)

\(K_1 = K_{1_{damping}}K_{1_{dephasing}}, K_2 = K_{1_{damping}}K_{2_{dephasing}},\)

\(K_3 = K_{2_{damping}}K_{1_{dephasing}}, K_4 = K_{2_{damping}}K_{2_{dephasing}}\)

该噪声模型需要三个参数, T1,T2和量子门时间参数 ,p0和p1的形式如下:

\[\begin{split}\begin{array}{c} p 0=p_{\text {damping}}=1-e^{-\frac{t_{\text {gate}}}{T_{1}}} \\ p 1=p_{\text {dephasing}}=0.5 *\left(1-e^{-\left(\frac{t_{\text {gate}}}{T_{2}}-\frac{t_{\text {gate}}}{2 T_{1}}\right)}\right) \end{array}\end{split}\]

噪声参数的范围如下:

\[T_{1} \in[5,100], T_{2} \in\left[2,2 T_{1}\right]\]
DEPOLARIZING_KRAUS_OPERATOR

DEPOLARIZING_KRAUS_OPERATOR去极化噪声模型,即单量子比特有一定的概率被完全混合态I/2代替, 它的kraus算符和表示方法如下所示:

\(K_1 = \sqrt{1 - 3p/4} × I, K_2 = \sqrt{p}/2 × X\)

\(K_3 = \sqrt{p}/2 × Y, K_4 = \sqrt{p}/2 × Z\)

其中I、X、Y、Z分别代表其量子逻辑门对应的矩阵

需要一个噪声参数

BITFLIP_KRAUS_OPERATOR

BITFLIP_KRAUS_OPERATOR是比特反转噪声模型,它的kraus算符和表示方法如下所示:

\(K_1 = \begin{bmatrix} \sqrt{1 - p} & 0 \\ 0 & \sqrt{1 - p} \end{bmatrix}, K_2 = \begin{bmatrix} 0 & \sqrt{p} \\ \sqrt{p} & 0 \end{bmatrix}\)

需要一个噪声参数。

BIT_PHASE_FLIP_OPRATOR

BIT_PHASE_FLIP_OPRATOR是比特-相位反转噪声模型,它的kraus算符和表示方法如下所示:

\(K_1 = \begin{bmatrix} \sqrt{1 - p} & 0 \\ 0 & \sqrt{1 - p} \end{bmatrix}, K_2 = \begin{bmatrix} 0 & -i \times \sqrt{p} \\ i \times \sqrt{p} & 0 \end{bmatrix}\)

需要一个噪声参数。

PHASE_DAMPING_OPRATOR

PHASE_DAMPING_OPRATOR是相位阻尼噪声模型,它的kraus算符和表示方法如下所示:

\(K_1 = \begin{bmatrix} 1 & 0 \\ 0 & \sqrt{1 - p} \end{bmatrix}, K_2 = \begin{bmatrix} 0 & 0 \\ 0 & \sqrt{p} \end{bmatrix}\)

需要一个噪声参数。

双门噪声模型

双门噪声模型同样也分为上述几种:DAMPING_KRAUS_OPERATOR、DEPHASING_KRAUS_OPERATOR、DECOHERENCE_KRAUS_OPERATOR、DEPOLARIZING_KRAUS_OPERATOR、BITFLIP_KRAUS_OPERATOR、BIT_PHASE_FLIP_OPRATOR、PHASE_DAMPING_OPRATOR。 它们的输入参数与单门噪声模型一致,双门噪声模型的kraus算符和表示与单门噪声模型存在着对应关系:假设单门噪声模型为: \(\{ K1, K2 \}\) ,那么对应的双门噪声模型为 \(\{K1\otimes K1, K1\otimes K2, K2\otimes K1, K2\otimes K2\}\)

接口介绍

全振幅虚拟机在进行含噪声模拟时,只需要在初始化前设置一些量子逻辑门的噪声模型和对应的参数即可。

目前QPanda2中含噪声量子逻辑门支持的噪声模型有:

class NoiseModel:
    BITFLIP_KRAUS_OPERATOR
    BIT_PHASE_FLIP_OPRATOR
    DAMPING_KRAUS_OPERATOR
    DECOHERENCE_KRAUS_OPERATOR
    DEPHASING_KRAUS_OPERATOR
    DEPOLARIZING_KRAUS_OPERATOR
    PHASE_DAMPING_OPRATOR

使用 Noise 类接口设置噪声模型参数:

def add_noise_model(self, noise_model: NoiseModel, gate_type: GateType, prob: float) -> None:
def add_noise_model(self, noise_model: NoiseModel, gate_types: List[GateType], prob: float) -> None:
def add_noise_model(self, noise_model: NoiseModel, gate_type: GateType, prob: float, qubits: QVec) -> None:
def add_noise_model(self, noise_model: NoiseModel, gate_types: List[GateType], prob: float, qubits: QVec) -> None:
def add_noise_model(self, noise_model: NoiseModel, gate_type: GateType, prob: float, qubits: List[QVec]) -> None:

第一个参数为噪声模型类型,第二个参数为量子逻辑门类型,第三个参数为噪声模型所需的参数, 第四个参数是对单个比特设置噪声参数(包含单门和双门),若没有第四个参数则对所有的比特设置相应的噪声模型。

对于需要输入三个参数的噪声类型,接口如下:

def add_noise_model(self, noise_model: NoiseModel, gate_type: GateType, t1: float, t2: float, t_gate: float) -> None:
def add_noise_model(self, noise_model: NoiseModel, gate_types: List[GateType], t1: float, t2: float, t_gate: float) -> None:
def add_noise_model(self, noise_model: NoiseModel, gate_type: GateType, t1: float, t2: float, t_gate: float, qubits: QVec) -> None:
def add_noise_model(self, noise_model: NoiseModel, gate_types: List[GateType], t1: float, t2: float, t_gate: float, qubits: QVec) -> None:
def add_noise_model(self, noise_model: NoiseModel, gate_type: GateType, t1: float, t2: float, t_gate: float, qubits: List[QVec]) -> None:

接口参数意义与之前的接口类似

除此之外,噪声模型还支持设置测量噪声,表示执行测量操作本身带入到系统的噪声,与单门操作触发的算子噪声类似,

def add_measure_error(self, noise_model: NoiseModel, prob: float, qubits: QVec = ...) -> None:
def add_measure_error(self, noise_model: NoiseModel, t1: float, t2: float, t_gate: float, qubits: QVec = ...) -> None:

用法类似于量子逻辑门的噪声模型,第一个参数为噪声模型类型,后面的参数和量子逻辑门的噪声参数。

重置噪声:

def set_reset_error(self, p0: float, p1: float, qubits: QVec) -> None:

p0 表示重置到 \(\left|0\right\rangle\) 的概率,p1表示重置到 \(\left|1\right\rangle\) 的概率,未被重置的概率为 1-p0-p1。

读出噪声:

def set_readout_error(self, prob_list: List[List[float]], qubits: QVec = ...) -> None:

probs_list 为四个元素,两两一组,如 probs_list = {{f0, 1 - f0},{1 - f1, f1}};, 表示当测量终态为 \(\left|0\right\rangle\) ,读出为0的概率为f0,读出为1的概率为1-f0;当测量终态为 \(\left|1\right\rangle\) 时,读出为0的概率为1-f1,读出为1的概率为f1。

第二个参数为读出噪声作用的比特。

读出噪声不是量子噪声,而是经典仪器从低温量子态获取到结果,到室温过程中环境造成的干扰。

噪声模型还支持设置带有相位角旋转的量子逻辑门的旋转误差,其接口使用方式如下:

def set_rotation_error(self, error: float) -> None:

实例

from pyqpanda import *
import numpy as np

if __name__ == "__main__":
    qvm = CPUQVM()
    qvm.init_qvm()
    q = qvm.qAlloc_many(4)
    c = qvm.cAlloc_many(4)

    # 创建噪声模型,并添加设置噪声参数
    noise = Noise()
    noise.add_noise_model(NoiseModel.BITFLIP_KRAUS_OPERATOR, GateType.PAULI_X_GATE, 0.1)
    qv0 = [q[0], q[1]]
    noise.add_noise_model(NoiseModel.DEPHASING_KRAUS_OPERATOR, GateType.HADAMARD_GATE, 0.1, qv0)
    qves = [[q[0], q[1]], [q[1], q[2]]]
    noise.add_noise_model(NoiseModel.DAMPING_KRAUS_OPERATOR, GateType.CNOT_GATE, 0.1, qves)

    f0 = 0.9
    f1 = 0.85
    noise.set_readout_error([[f0, 1 - f0], [1 - f1, f1]])
    noise.set_rotation_error(0.05)

    prog = QProg()
    prog << X(q[0]) << H(q[0]) \
         << CNOT(q[0], q[1]) \
         << CNOT(q[1], q[2]) \
         << CNOT(q[2], q[3]) \
         << measure_all(q, c)

    # 运行量子程序时,加入噪声模型。默认为空噪声模型,即无噪声
    result = qvm.run_with_configuration(prog, c, 1000, noise)
    print(result)

运行结果:

{'0000': 347, '0001': 55, '0010': 50, '0011': 43, '0100': 41, '0101': 18, '0110': 16, '0111': 34, '1000': 50, '1001': 18, '1010': 18, '1011': 37, '1100': 15, '1101': 49, '1110': 42, '1111': 167}

程序在无噪声的理想情况下,结果应该当为等概率的 0000 和 1111。结果中的其他测量值,为噪声带来的影响。

部分振幅量子虚拟机

目前用经典计算机模拟量子虚拟机的主流解决方案有全振幅与单振幅两种。除此之外,还有部分振幅量子虚拟机,该方案[1]能在更低的硬件条件下,实现更高的模拟效率。

背景介绍

在过去的几年里,半导体量子芯片也取得了很大进展[3-5]。量子霸权声称如果制造出一个由50个量子位组成的装置,经典计算机的极限将被超越(即直接模拟50个量子位需要大约16-PB的RAM来存储完整的向量)。

Google和ibm团队已经提出了一些有效的方法来模拟49量子位以上的低深度电路(例如延迟纠缠门)[2]。

在这里我们提出了一种优化低深度大采样数量子电路经典模拟的方案并对其进行了64量子位模拟。

具体来说,大致方案是通过将几个控制Z (CZ)门变换为测量门和单量子位门,将电路映射到多个额外的子电路中。

这些子电路由两个块组成,它们之间没有任何量子比特纠缠,从而将 一个N量子比特的模拟问题转化为一组N/2的电路求解问题

我们的方法是类似于二维网格的平衡切割,对于一个CZ门,分裂成四个子电路,然后将所有子电路的结果相加,以重建最终状态。

模拟方案细节

部分振幅量子虚拟机的基本思想是将大比特的量子程序拆分成若干个小比特量子程序,每个小比特量子线路使用全振幅算法计算,量子程序的拆分规则如下: 若量子线路中出现跨节点的双量子逻辑门,则对量子程序进行拆分。即以量子程序中量子比特数为总量子比特数的一半或接近一半为分界线,例如总量子比特数为10,则4号比特与5号比特之间为分界线。 双量子逻辑门的控制位量子比特与目标位量子比特分别处于界线的两侧,称为跨节点,例如总量子比特数为10,CNOT(1,5)为跨节点,CNOT(1,4)则没有跨节点。

一个CZ门可以转化为两组测量门和单量子位门的组合,具体的

\[\mathrm{CZ}=P_0 \times I+P_1 \times Z\]

其中I表示单位矩阵,Z表示Pauli-Z矩阵

\[\begin{split}P_0=\left(\begin{array}{ll}1 & 0 \\ 0 & 0\end{array}\right) P_1=\left(\begin{array}{ll}0 & 0 \\ 0 & 1\end{array}\right)\end{split}\]

对于其他双量子逻辑门,如CR、iSWAP、SqiSWAP等, 可以通过量子逻辑门转化算法将其转换成单量子逻辑门和支持拆分的双量子逻辑门的组合,再对双量子逻辑门进行拆分,拆分过程的示例图如下:

_images/part.png

上图是拆分的一个例子。第一行是原来的电路。框中的两个CZ门将前四位和最后四位纠缠在一起。接着,转换左CZ门,原电路等效于第二行电路的加法。继续右CZ门被转换,在第三行产生四个电路。原电路的最终状态等于所有变换电路的加法。第三行中的虚线将每个电路分成两部分,在两部分中可以独立地进行模拟。

使用介绍

class PartialAmpQVM(QuantumMachine)

量子部分振幅模拟器类,该类实现了基于部分振幅拆分图算法的量子线路模拟。

__init__()

初始化 PartialAmpQVM 类实例。

get_prob_dict(qubit_list: QVec) Dict[str, float]

获取测量概率结果的字典形式。

参数:

qubit_list (QVec) -- 用于测量的量子比特列表。

返回:

包含测量概率的字典,键为测量结果的二进制字符串,值为对应的测量概率。

返回类型:

Dict[str, float]

抛出:

run_fail -- 获取测量概率失败。

init_qvm(type: BackendType = BackendType.CPU) None

初始化量子虚拟机。

参数:

type (BackendType, optional) -- 子图计算后端的类型。默认为 BackendType.CPU。

返回:

无返回值。

pmeasure_bin_index(bin_index: str) complex

获取指定二进制索引的量子态振幅。

参数:

bin_index (str) -- 二进制索引。

返回:

指定二进制索引的量子态振幅。

返回类型:

complex

抛出:

run_fail -- 获取振幅失败。

pmeasure_dec_index(dec_index: str) complex

获取指定十进制索引的量子态振幅。

参数:

dec_index (str) -- 十进制索引。

返回:

指定十进制索引的量子态振幅。

返回类型:

complex

抛出:

run_fail -- 获取振幅失败。

pmeasure_subset(index_list: List[str]) Dict[str, complex]

获取量子态部分子集的振幅。

参数:

index_list (List[str]) -- 量子态索引列表。

返回:

包含量子态子集振幅的字典,键为量子态索引,值为对应的量子态振幅。

返回类型:

Dict[str, complex]

抛出:

run_fail -- 获取振幅失败。

run(qprog: QProg, noise_model: Noise = NoiseModel()) None

运行量子程序,拆分原始线路,生成子图。

参数:
  • qprog (QProg) -- 要运行的量子程序。

  • noise_model (Noise, optional) -- 噪声模型。默认为空的噪声模型。

返回:

无返回值。

抛出:

run_fail -- 运行量子程序失败。

其使用方式与前面介绍的量子虚拟机模块非常类似,首先通过 PartialAmpQVM 初始化一个部分振幅量子虚拟机对象用于管理后续一系列行为

from pyqpanda import *
from numpy import pi
machine = PartialAmpQVM()

然后是量子程序的初始化、构建与装载过程,以QPanda2的部分振幅示例程序来演示:

machine.init_qvm()

q = machine.qAlloc_many(10)
c = machine.cAlloc_many(10)

# 构建量子程序
prog = QProg()
prog << hadamard_circuit(q)\
     << CZ(q[1], q[5])\
     << CZ(q[3], q[7])\
     << CZ(q[0], q[4])\
     << RZ(q[7], pi / 4)\
     << RX(q[5], pi / 4)\
     << RX(q[4], pi / 4)\
     << RY(q[3], pi / 4)\
     << CZ(q[2], q[6])\
     << RZ(q[3], pi / 4)\
     << RZ(q[8], pi / 4)\
     << CZ(q[9], q[5])\
     << RY(q[2], pi / 4)\
     << RZ(q[9], pi / 4)\
     << CZ(q[2], q[3])

machine.run(prog)

部分接口使用如下:

  • pmeasure_bin_index(string) ,使用示例

    result = machine.pmeasure_bin_index("0000000000")
    print(result)
    

    结果输出如下:

    (-0.00647208746522665-0.006472080945968628j)
    
  • pmeasure_dec_index(string) ,使用示例

    result = machine.pmeasure_dec_index("1")
    print(result)
    

    结果输出如下:

    (-4.413170804465268e-19-0.009152913087920392j)
    
  • pmeasure_subset(state_index) ,使用示例

    state_index = ["0", "1", "2"]
    result = machine.pmeasure_subset(state_index)
    print(result)
    

    结果输出如下:

    {'0': (-0.006472086912079613-0.00647208691207961j),
     '1': (-4.413170804465268e-19-0.009152913087920392j),
     '2': (-3.0357660829594124e-18-0.009152913087920392j)}
    

参考文献

[1] 64-qubit quantum circuit simulation Zhao-Yun Chen1,Qi Zhou,Cheng Xue,Guang-Can Guo,Guo-PingGuo(2020).
[2] Pednault E, Gunnels JA, Nannicini G, et al. Breaking the 49-qubit barrier in the simulation of quantum circuits. Preprint at https://arxiv.org/abs/1710.05867v1 (2017).
[3] Cao G, Li HO, Tu T, et al. Ultrafast universal quantum control of a quantum-dot charge qubit using Landau-Zener-Stuckelberg interference. Nat Commun 4: 1401 (2013).
[4] Li HO, Cao G, Yu GD, et al. Conditional rotation of two strongly coupled semiconductor charge qubits. Nat Commun 6: 7681 (2015).
[5] Li HO, Cao G, Yu GD, et al. Controlled quantum operations of a semiconductor three-qubit System. Phys Rev A 9: 024015 (2018).

单振幅量子虚拟机

短期内,量子霸权的存在,超出了现有经典算法在最先进计算机或超算上的能力,这刺激了最近在模拟量子电路的经典算法方面的进展。

与适用于低比特高深度的全向量模拟相比,单振幅模拟器将量子电路的模拟推广到一个无向图形模型上,并在精确推理的背景下,利用变量消去算法进行了计算。

首先我们在量子线路演化中引入费曼路径积分方法。

我们用酉矩阵的乘积来表示量子电路 \(U^{(t)}\) ,其中t表示不同的时钟周期。

在电路的最后一个周期后,我们引入以下符号来表示特定量子位串的振幅。

\[\langle x|\mathcal{U}| 0 \ldots 0\rangle=\sum_{\left\{b^t\right\}} \prod_{t=0}^{d-1}\left\langle b^{t+1}\left|U^{(t)}\right| b^t\right\rangle, \quad\left|b^d\right\rangle=|x\rangle\]

这里 \(\left|b^t\right\rangle=\otimes_{j=1}^n\left|b_j^t\right\rangle\) ,以及 \(\left|b_i^t\right\rangle\) 对应量子态 \(|0\rangle\)\(|1\rangle\) 的第 \(j\)-th 比特。

上述表达式可以看作是n量子位系统的 \(\left\{b^0, \ldots, b^d\right\}\) 的费曼路径积分形式。

根据上文所说,一个量子线路是多个酉矩阵的乘积,即 \(\mathcal{U}=U_g \cdots U_1\) ,其中对于一个对角矩阵可以用如下表述:

\[U=\sum_{b \in\{0,1\}} \psi_U(b)|b\rangle\langle b| \quad \text { (diagonal) }\]

其中 \(\psi_U(b)\) 是一个布尔变量的复函数,对于一个非对角矩阵,比如 \(\mathrm{H}, \mathrm{X}^{1 / 2}, \mathrm{Y}^{1 / 2}\) ,有

\[U=\sum_{b, b^{\prime} \in\{0,1\}} \psi_U\left(b^{\prime}, b\right)\left|b^{\prime}\right\rangle\langle b| \quad \text { (non-diagonal) }\]

其中 \(\psi_U\left(b, b^{\prime}\right)\) 是两个布尔变量的复函数,例如对于一个H门, \(\psi_{\mathrm{H}}(1,1)= -1 / \sqrt{2}\) , 其他项等于 \(1 / \sqrt{2}\) 。 一个对角双门,例如CZ,可以写成如下形式

\[U=\mathrm{CZ}=\sum_{b, b^{\prime} \in\{0,1\}} \psi_{\mathrm{CZ}}\left(b, b^{\prime}\right)\left|b, b^{\prime}\right\rangle\left\langle b, b^{\prime}\right|,\]

根据对角矩阵和非对角矩阵的性质,可以在有向无环图中分别用不同形状表示,以如下量子线路为例

_images/single1.png

假设以初态 \(| 00\rangle\) 计算量子态末态为 \(| 00\rangle\) 的概率,对应的有向无环图模型为

_images/single2.png

因为初态和末态是确定的,我们有 \(b_0^0=b_0^2=b_1^0=b_1^2=0\) 。图可以简化为如下形式:

_images/single3.png

这个图的树宽为2 ,我们可以计算出

\[\begin{split}\begin{array}{r} \langle 00|C| 00\rangle=\sum_{b_0^1, b_1^1} \psi_{\mathrm{H}}\left(0, b_0^1\right) \psi_{\mathrm{CZ}}\left(b_0^1, b_1^1\right) \psi_{\mathrm{H}}\left(b_0^1, 0\right) \\ \psi_{\mathrm{H}}\left(0, b_1^1\right) \psi_{\mathrm{H}}\left(b_1^1, 0\right) . \end{array}\end{split}\]

函数 \(\psi_{\mathrm{H}}\) 对应的H门映射表可以写为

\[\begin{split}\begin{array}{|ll|c|} \hline 0 & 0 & 1 / \sqrt{2} \\ 0 & 1 & 1 / \sqrt{2} \\ 1 & 0 & 1 / \sqrt{2} \\ 1 & 1 & -1 / \sqrt{2} \\ \hline \end{array}\end{split}\]

函数 \(\psi_{\mathrm{CZ}}\) 对应的CZ门映射表可以写为

\[\begin{split}\begin{array}{|ll|c|} \hline 0 & 0 & 1 \\ 0 & 1 & 1 \\ 1 & 0 & 1 \\ 1 & 1 & -1 \\ \hline \end{array}\end{split}\]

上面的等式就可以重写为

\[\langle 00|C| 00\rangle=\sum_{b_0^1, b_1^1} \tau_1\left(b_0^1, b_1^1\right)\]

其中表中 \(\tau_1\) 的映射关系为

\[\begin{split}\begin{array}{|ll|c|} \hline 0 & 0 & 1 / 4 \\ 0 & 1 & 1 / 4 \\ 1 & 0 & 1 / 4 \\ 1 & 1 & -1 / 4 \\ \hline \end{array}\end{split}\]

如果我们把所有的 \(b_1^1\) 相加可以得到

\[\langle 00|C| 00\rangle=\sum_{b_0^1} \tau_2\left(b_0^1\right)\]

其中 \(\tau_2\)

\[\begin{split}\begin{array}{|c|c|} \hline 0 & 1 / 2 \\ 1 & 0 \\ \hline \end{array}\end{split}\]

最终, 对 \(b_0^1\) 求和,可以计算出末态的概率

\[\langle 00|C| 00\rangle=1 / 2 .\]
class SingleAmpQVM(QuantumMachine)

量子单振幅模拟器类

该类实现了基于单振幅的量子线路模拟,借助于费曼积分路径和quickBB,可以快速模拟大比特稀疏量子线路的单个振幅

__init__()

初始化单振幅模拟器类实例。

pmeasure_bin_amplitude(bin_string: str) complex

获取指定二进制字符串的量子态振幅。

参数:

bin_string (str) -- 二进制字符串。

返回:

指定二进制字符串的量子态振幅。

返回类型:

complex

抛出:

run_fail -- 获取振幅失败。

pmeasure_bin_index(bin_string: str) float

获取指定二进制字符串的量子态概率振幅。

参数:

bin_string (str) -- 二进制字符串。

返回:

指定二进制字符串的量子态概率振幅。

返回类型:

float

抛出:

run_fail -- 获取概率振幅失败。

pmeasure_dec_amplitude(dec_string: str) complex

获取指定十进制字符串的量子态振幅。

参数:

dec_string (str) -- 十进制字符串。

返回:

指定十进制字符串的量子态振幅。

返回类型:

complex

抛出:

run_fail -- 获取振幅失败。

pmeasure_dec_index(dec_string: str) float

获取指定十进制字符串的量子态概率振幅。

参数:

dec_string (str) -- 十进制字符串。

返回:

指定十进制字符串的量子态概率振幅。

返回类型:

float

抛出:

run_fail -- 获取概率振幅失败。

run(prog: QProg, qubit_list: QVec, max_rank: int = 30, alloted_time: int = 5) None

运行量子程序。

参数:
  • prog (QProg) -- 要运行的量子程序。

  • qubit_list (QVec) -- 用于运行的量子比特列表。

  • max_rank (int, optional) -- 最大秩限制。默认为 30。

  • alloted_time (int, optional) -- 允许quickBB的运行时间。默认为 5。

返回:

无返回

其使用方式与前面介绍的量子虚拟机模块非常类似,首先通过 SingleAmpQVM 初始化一个单振幅量子虚拟机对象用于管理后续一系列行为。

from pyqpanda import *
from numpy import pi

qvm = SingleAmpQVM()

然后是量子程序的初始化、构建与装载过程:

qvm.init_qvm()

qv = qvm.qAlloc_many(10)
cv = qvm.cAlloc_many(10)

prog = QProg()

# 构建量子程序
prog << CZ(qv[1], qv[5])\
    << CZ(qv[3], qv[5])\
    << CZ(qv[2], qv[4])\
    << CZ(qv[3], qv[7])\
    << CZ(qv[0], qv[4])\
    << RY(qv[7], pi / 2)\
    << RX(qv[8], pi / 2)\
    << RX(qv[9], pi / 2)\
    << CR(qv[0], qv[1], pi)\
    << CR(qv[2], qv[3], pi)\
    << RY(qv[4], pi / 2)\
    << RZ(qv[5], pi / 4)\
    << RX(qv[6], pi / 2)\
    << RZ(qv[7], pi / 4)\
    << CR(qv[8], qv[9], pi)\
    << CR(qv[1], qv[2], pi)\
    << RY(qv[3], pi / 2)\
    << RX(qv[4], pi / 2)\
    << RX(qv[5], pi / 2)\
    << CR(qv[9], qv[1], pi)\
    << RY(qv[1], pi / 2)\
    << RY(qv[2], pi / 2)\
    << RZ(qv[3], pi / 4)\
    << CR(qv[7], qv[8], pi)

然后是调用计算接口,需要注意的是, run 方法是调用计算振幅前必须调用的函数,用于正确生成有向无环图和计算路径,

pmeasure_bin_index ,使用时需要结合 run 方法。用法示例:

# run 有三个参数,默认2个,
# 第一个执行的量子程序
# 第二个为申请的量子比特
# 第三个为最大RANK,这里根据内存设置,默认30
# 第四个就是quickBB优化的最大运行时间,默认5s

qvm.run(prog, qv)
bin_result = qvm.pmeasure_bin_index("0001000000")
print("0001000000 : ", bin_result)

结果输出如下:

0001000000 :  0.001953123603016138

pmeasure_dec_index ,使用时需要结合 run 方法。用法示例:

qvm.run(prog, qv)
dec_result = qvm.pmeasure_dec_index("2")
print("2 : ",dec_result)

结果输出如下:

2 :  0.001953123603016138

张量网络量子虚拟机

对于一个 \(N\) 个量子比特的自旋体系,对应的希尔伯特空间维数为 \(2^{N}\)

对于该复杂系统的状态演化,传统的全振幅模拟器将其看做一个有 \(2^{N}\) 个元素的一维向量。

然而从张量网络的角度来看,整个系统量子态的系数对应 \(2^{N}\) 维张量(即N阶张量,即有 \(N\) 个指标,每个指标的维数是2),量子操作算符的系数为 \(2^{2N}\) 维张量( \(2N\) 阶张量,即有个 \(2N\) 指标,每个指标的维数是2),我们可以用如下图形来表示量子态:

_images/state.png

当量子系统的自旋个数增加时,量子态系数的个数随指数增加,称为指数墙问题,这一障碍限制了传统全振幅模拟器的最大模拟自旋数和模拟性能。

但是可通过张量网络处理这一问题,从而绕过指数墙障碍,在张量网络中,我们对量子系统的模拟,包括量子逻辑门操作和测量操作,均可以通过对于张量的缩并与分解来实现。矩阵乘积态是张量网络中最常用的表示形式,在多线性代数中称为张量列或TT(Tensor-Train),示意图如下。

_images/MPS.png

将量子态分解成等式右边的表示形式,对于量子线路中部分量子逻辑门操作,可以将全局问题转化为局部的张量处理问题,从而有效地降低了时间复杂度和空间复杂度。

pyqpanda 中可以通过 MPSQVM 类实现用张量网络模拟量子电路。

class MPSQVM(QuantumMachine)

该类实现了基于矩阵乘积态(MPS)的量子线路模拟。可以获取测量结果、模拟量子态等操作。

__init__()

初始化 MPSQVM 类实例。

pmeasure(qubit_list: QVec, select_max: int = -1) List[Tuple[int, float]]

获取量子测量概率分布的列表形式。

参数:
  • qubit_list (QVec) -- 用于测量的量子比特列表。

  • select_max (int, optional) -- 返回的元素数量上限。默认为 -1,表示无限制。

返回:

包含量子测量结果的列表,每个元组包含测量结果的索引和对应的概率。

返回类型:

List[Tuple[int, float]]

pmeasure_bin_index(program: QProg, string: str) complex

获取指定二进制字符串的量子态振幅。

参数:
  • program (QProg) -- 要运行的量子程序。

  • string (str) -- 二进制字符串。

返回:

指定二进制字符串的量子态振幅。

返回类型:

complex

抛出:

run_fail -- 获取振幅失败。

pmeasure_bin_subset(program: QProg, string_list: List[str]) List[complex]

获取一组二进制字符串的量子态振幅。

参数:
  • program (QProg) -- 要运行的量子程序。

  • string_list (List[str]) -- 二进制字符串列表。

返回:

一组二进制字符串的量子态振幅。

返回类型:

List[complex]

抛出:

run_fail -- 获取振幅失败。

pmeasure_dec_index(program: QProg, string: str) complex

获取指定十进制字符串的量子态振幅。

参数:
  • program (QProg) -- 要运行的量子程序。

  • string (str) -- 十进制字符串。

返回:

指定十进制字符串的量子态振幅。

返回类型:

complex

抛出:

run_fail -- 获取振幅失败。

pmeasure_dec_subset(program: QProg, string_list: List[str]) List[complex]

获取一组十进制字符串的量子态振幅。

参数:
  • program (QProg) -- 要运行的量子程序。

  • string_list (List[str]) -- 十进制字符串列表。

返回:

一组十进制字符串的量子态振幅。

返回类型:

List[complex]

抛出:

run_fail -- 获取振幅失败。

prob_run_dict(program: QProg, qubit_list: QVec, select_max: int = -1) Dict[str, float]

运行量子程序并获取测量概率结果的字典形式。

参数:
  • program (QProg) -- 要运行的量子程序。

  • qubit_list (QVec) -- 用于测量的量子比特列表。

  • select_max (int, optional) -- 返回的元素数量上限。默认为 -1,表示无限制。

返回:

包含测量概率的字典,键为测量结果的二进制字符串,值为对应的测量概率。

返回类型:

Dict[str, float]

抛出:

run_fail -- 运行量子程序失败。

prob_run_list(program: QProg, qubit_list: QVec, select_max: int = -1) List[float]

运行量子程序并获取测量概率结果的列表形式。

参数:
  • program (QProg) -- 要运行的量子程序。

  • qubit_list (QVec) -- 用于测量的量子比特列表。

  • select_max (int, optional) -- 返回的元素数量上限。默认为 -1,表示无限制。

返回:

包含测量概率的列表。

返回类型:

List[float]

抛出:

run_fail -- 运行量子程序失败。

prob_run_tuple_list(program: QProg, qubit_list: QVec, select_max: int = -1) List[Tuple[int, float]]

运行量子程序并获取测量概率结果的元组列表形式。

参数:
  • program (QProg) -- 要运行的量子程序。

  • qubit_list (QVec) -- 用于测量的量子比特列表。

  • select_max (int, optional) -- 返回的元素数量上限。默认为 -1,表示无限制。

返回:

包含测量概率的元组列表,每个元组包含测量结果的索引和对应的概率。

返回类型:

List[Tuple[int, float]]

抛出:

run_fail -- 运行量子程序失败。

quick_measure(qubit_list: QVec, shots: int) Dict[str, int]

快速进行多次测量。

参数:
  • qubit_list (QVec) -- 用于测量的量子比特列表。

  • shots (int) -- 测量操作的重复次数。

返回:

包含多次测量结果的字典,键为测量结果的二进制字符串,值为对应的出现次数。

返回类型:

Dict[str, int]

抛出:

run_fail -- 运行量子程序失败。

set_measure_error(noise_model: NoiseModel, error_rate: float, gate_type: GateType = GateType.HADAMARD_GATE, qubits: List[QVec] = []) None

设置测量误差模型。

参数:
  • noise_model (NoiseModel) -- 噪声模型。

  • error_rate (float) -- 误差率。

  • gate_type (GateType, optional) -- 误差应用的门类型。默认为 GateType.HADAMARD_GATE。

  • qubits (List[QVec], optional) -- 用于应用误差的量子比特列表。默认为空列表。

返回:

无返回值。

set_mixed_unitary_error(gate_type: GateType, error_matrix: List[List[complex]], qubits: List[QVec] = []) None

设置混合幺正误差模型。

参数:
  • gate_type (GateType) -- 门类型。

  • error_matrix (List[List[complex]]) -- 误差矩阵。

  • qubits (List[QVec], optional) -- 用于应用误差的量子比特列表。默认为空列表。

返回:

无返回值。

set_noise_model(noise_model: NoiseModel, gate_type: GateType, error_rate: float, qubits: List[QVec] = []) None

设置噪声模型。

参数:
  • noise_model (NoiseModel) -- 噪声模型。

  • gate_type (GateType) -- 误差应用的门类型。

  • error_rate (float) -- 误差率。

  • qubits (List[QVec], optional) -- 用于应用误差的量子比特列表。默认为空列表。

返回:

无返回值。

set_readout_error(readout_params: List[List[float]], qubits: QVec) None

设置读数误差模型。

参数:
  • readout_params (List[List[float]]) -- 读数误差参数列表。

  • qubits (QVec) -- 用于应用误差的量子比特列表。

返回:

无返回值。

set_reset_error(reset_0_param: float, reset_1_param: float) None

设置重置误差模型。

参数:
  • reset_0_param (float) -- 重置到0态的参数。

  • reset_1_param (float) -- 重置到1态的参数。

返回:

无返回值。

set_rotation_error(param: float) None

设置旋转门误差模型。

参数:

param (float) -- 误差参数。

返回:

无返回值。

和许多其他模拟器的使用方法一样,都具有相同的量子虚拟机接口,比如下述简单的使用示例代码:

from numpy import pi
from pyqpanda import *

# 构建量子虚拟机
qvm = MPSQVM()

# 初始化操作
qvm.set_configure(64, 64)
qvm.init_qvm()

q = qvm.qAlloc_many(10)
c = qvm.cAlloc_many(10)

# 构建量子程序
prog = QProg()
prog << hadamard_circuit(q)\
    << CZ(q[2], q[4])\
    << CZ(q[3], q[7])\
    << CNOT(q[0], q[1])\
    << Measure(q[0], c[0])\
    << Measure(q[1], c[1])\
    << Measure(q[2], c[2])\
    << Measure(q[3], c[3])

# 量子程序运行100次,并返回测量结果
result = qvm.run_with_configuration(prog, c, 100)

# 打印量子态在量子程序多次运行结果中出现的次数
print(result)

qvm.finalize()

以下示例展示了张量网络模拟器计算部分接口的使用方式

from numpy import pi
from pyqpanda import *

qvm = MPSQVM()
qvm.set_configure(64, 64)
qvm.init_qvm()

q = qvm.qAlloc_many(10)
c = qvm.cAlloc_many(10)

prog = QProg()
prog << hadamard_circuit(q)\
    << CZ(q[2], q[4])\
    << CZ(q[3], q[7])\
    << CNOT(q[0], q[1])\
    << CZ(q[3], q[7])\
    << CZ(q[0], q[4])\
    << RY(q[7], pi / 2)\
    << RX(q[8], pi / 2)\
    << RX(q[9], pi / 2)\
    << CR(q[0], q[1], pi)\
    << CR(q[2], q[3], pi)\
    << RY(q[4], pi / 2)\
    << RZ(q[5], pi / 4)\
    << Measure(q[0], c[0])\
    << Measure(q[1], c[1])\
    << Measure(q[2], c[2])

# Monte Carlo采样模拟接口
result0 = qvm.run_with_configuration(prog, c, 100)

# 概率测量接口
result1 = qvm.prob_run_dict(prog, [q[0], q[1], q[2]], -1)

print(result0)
print(result1)

qvm.finalize()

上述代码中 run_with_configurationprob_run_dict 接口分别用于Monte Carlo采样模拟和概率测量,他们分别输出模拟采样的结果和对应振幅的概率,上述程序的计算结果如下

# Monte Carlo 采样模拟结果
{'0000000000': 7,
 '0000000001': 12,
 '0000000010': 13,
 '0000000011': 10,
 '0000000100': 16,
 '0000000101': 14,
 '0000000110': 12,
 '0000000111': 16}

# 概率测量结果
{'000': 0.12499999999999194,
 '001': 0.12499999999999185,
 '010': 0.12499999999999194,
 '011': 0.124999999999992,
 '100': 0.12499999999999198,
 '101': 0.12499999999999194,
 '110': 0.12499999999999198,
 '111': 0.12499999999999208}

密度矩阵模拟器

目前量子计算机的主要局限在于通用量子计算机所需的量子系统规模非常大,技术实现困难,因而人们主要利用中小规模量子体系,解决特定问题。

对于纯态和混合态量子比特系统,需要找到一种在低比特情况下,正确模拟噪声测量以及对哈密顿算符期望进行求解,而 密度矩阵模拟器 提供这一问题的解决方案。

对于混合态,态矢已难以完整的表示系统的量子态,一般使用密度矩阵来描述:

\[\begin{aligned} \rho = \sum_{i}^{n} p_i|\varphi_i\rangle\langle\varphi_i| \end{aligned}\]

对于纯态,可简化为

\[\rho = |\varphi\rangle\langle\varphi|\]

回到前文所述的混合态,其密度矩阵为:

\[\begin{split}\rho = \frac{1}{2}|0\rangle\langle 0| + \frac{1}{2}|1\rangle\langle 1| = \frac{1}{2} \begin{bmatrix} 1&0\\ 0&1 \end{bmatrix}\end{split}\]

而相同测量结果的 \(|\psi\rangle = \frac{1}{\sqrt 2}|0\rangle + \frac{1}{\sqrt 2}|1\rangle\) 纯态,其密度矩阵为:

\[\begin{split}\rho = |\psi\rangle\langle\psi| = \frac{1}{2} \begin{bmatrix} 1&1\\ 1&1 \end{bmatrix}\end{split}\]

由密度矩阵可见,两者的量子态是完全不同的。

对于纯态,有 \(tr(\rho^2) = 1\), 混合态 \(tr(\rho^2) < 1\)\(tr(A)\) 表示求矩阵 \(A\) 的迹,即n维矩阵 \(A\) 中对角线上元素之和。

对于一般的酉矩阵逻辑门,用密度矩阵表示其对系统的态演化:

\[\rho^{\prime} = U{\rho}U^{\dagger}\]

使用密度矩阵表示测量结果,测量得到结果m的概率为:

\[p(m) = tr(M_{m}^{\dagger}M_m\rho)\]

上式中 \(M_m\) 叫做测量算子,通常也叫做投影算符。以我们的计算基 \(|0\rangle\) 为例,其投影到 \(|0\rangle\) 的投影算符为 \(|0\rangle\langle 0|\) , 因此,测量得到 \(|0\rangle\) 的概率为:

\[p(|0\rangle) = tr(|0\rangle\langle 0||0\rangle\langle 0|\rho)\]

以之前混合态和纯态的例子计算其测量结果为:

\[\begin{split}\begin{aligned} 混合态: p(|0\rangle) = tr( \frac{1}{2} \begin{bmatrix} 1&0\\ 0&0 \end{bmatrix} \begin{bmatrix} 1&0\\ 0&0 \end{bmatrix} \begin{bmatrix} 1&0\\ 0&1 \end{bmatrix} ) =\frac{1}{2} \\ 纯态: p(|0\rangle) = tr( \frac{1}{2} \begin{bmatrix} 1&0\\ 0&0 \end{bmatrix} \begin{bmatrix} 1&0\\ 0&0 \end{bmatrix} \begin{bmatrix} 1&1\\ 1&1 \end{bmatrix} ) =\frac{1}{2} \\ \end{aligned}\end{split}\]

密度矩阵是表达量子态的另一种方式。而密度矩阵模拟器用于求解量子线路对应的密度矩阵,以及计算量子态概率分布、模拟含噪声量子线路和计算哈密顿量期望值等等。


pyqpanda 中可以通过 DensityMatrixSimulator 类实现用密度矩阵模拟器。和许多其他模拟器的使用方法一样,都具有相同的量子虚拟机接口:

class DensityMatrixSimulator(QuantumMachine)

该类是用于模拟密度矩阵的量子虚拟机。 该类提供了一系列方法用于模拟N比特的密度矩阵和约化密度矩阵的计算,以及直接获取不同噪声环境下量子线路模拟后的概率分布

get_density_matrix(prog: QProg) numpy.ndarray[numpy.complex128[m, n]]

执行量子程序并获取完整的密度矩阵。

参数:

prog (QProg) -- 量子程序。

返回:

完整的密度矩阵。

返回类型:

numpy.ndarray[numpy.complex128[m,n]]

抛出:

run_fail -- 获取密度矩阵时发生错误。

get_expectation(prog: QProg, hamiltonian: List[Tuple[Dict[int, str], float]], qubits: QVec) float
get_expectation(prog: QProg, hamiltonian: List[Tuple[Dict[int, str], float]], qubits: List[int]) float

执行量子程序并计算给定哈密顿量的期望值。

参数:
  • prog (QProg) -- 量子程序。

  • hamiltonian (List[Tuple[Dict[int,str],float]]) -- 哈密顿量。

  • qubits (QVec or List[int]) -- 选定的量子比特或量子比特列表。

返回:

选定量子比特上的哈密顿量期望值。

返回类型:

float

抛出:

run_fail -- 计算期望值时发生错误。

get_probabilities(prog: QProg) List[float]
get_probabilities(prog: QProg, qubits: QVec) List[float]
get_probabilities(prog: QProg, qubits: List[int]) List[float]
get_probabilities(prog: QProg, indices: List[str]) List[float]

执行量子程序并获取所有可能性的概率。

参数:
  • prog (QProg) -- 量子程序。

  • qubits (QVec or List[int]) -- 选定的量子比特或量子比特列表。

  • indices (List[str]) -- 选定的二进制索引列表。

返回:

量子程序的概率结果。

返回类型:

List[float]

抛出:

run_fail -- 获取概率时发生错误。

get_probability(prog: QProg, index: int) float
get_probability(prog: QProg, index: str) float

执行量子程序并获取给定索引的概率。

参数:
  • prog (QProg) -- 量子程序。

  • index (int or str) -- 测量索引(在 [0,2^N - 1] 范围内)。

返回:

量子程序的概率结果。

返回类型:

float

抛出:

run_fail -- 获取概率时发生错误。

get_reduced_density_matrix(prog: QProg, qubits: QVec) numpy.ndarray[numpy.complex128[m, n]]
get_reduced_density_matrix(prog: QProg, qubits: List[int]) numpy.ndarray[numpy.complex128[m, n]]

执行量子程序并获取选定量子比特的约化密度矩阵。

参数:
  • prog (QProg) -- 量子程序。

  • qubits (QVec or List[int]) -- 选定的量子比特或量子比特列表。

返回:

约化密度矩阵。

返回类型:

numpy.ndarray[numpy.complex128[m,n]]

抛出:

run_fail -- 获取约化密度矩阵时发生错误。

init_qvm(is_double_precision: bool = True) None

初始化量子虚拟机。

参数:

is_double_precision (bool, optional) -- 是否使用双精度(默认为 True)。

set_noise_model(arg0: numpy.ndarray[numpy.complex128[m, n]]) None
set_noise_model(arg0: numpy.ndarray[numpy.complex128[m, n]], arg1: List[GateType]) None
set_noise_model(arg0: List[numpy.ndarray[numpy.complex128[m, n]]]) None
set_noise_model(arg0: List[numpy.ndarray[numpy.complex128[m, n]]], arg1: List[GateType]) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float) None
set_noise_model(arg0: NoiseModel, arg1: List[GateType], arg2: float) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float, arg3: QVec) None
set_noise_model(arg0: NoiseModel, arg1: List[GateType], arg2: float, arg3: QVec) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float, arg3: List[QVec]) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float, arg3: float, arg4: float) None
set_noise_model(arg0: NoiseModel, arg1: List[GateType], arg2: float, arg3: float, arg4: float) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float, arg3: float, arg4: float, arg5: QVec) None
set_noise_model(arg0: NoiseModel, arg1: List[GateType], arg2: float, arg3: float, arg4: float, arg5: QVec) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float, arg3: float, arg4: float, arg5: List[QVec]) None

该方法用于设置噪声模型,以在模拟中引入量子门的错误。

参数:
  • arg0 (numpy.ndarray[numpy.complex128[m,n]] or List[numpy.ndarray[numpy.complex128[m,n]]] or NoiseModel or GateType or float) -- 噪声模型参数,可能的类型包括 numpy 数组、噪声模型、量子门类型(GateType)、浮点数等。

  • arg1 (Varies (See detailed descriptions)) -- 噪声模型的参数,具体类型取决于参数类型。

  • arg2 (float) -- 噪声强度,表示引入的错误概率。

  • arg3 (QVec or List[QVec] or QVec) -- 选定的量子比特列表(或量子比特),用于针对特定比特引入噪声(部分参数可能会用到)。

  • arg4 (Varies (See detailed descriptions)) -- 更多参数,具体类型和用途取决于参数类型。

  • arg5 (Varies (See detailed descriptions)) -- 更多参数,具体类型和用途取决于参数类型。

返回:

无返回值。

返回类型:

None

以下示例展示了密度矩阵模拟器计算部分接口的使用方式

from numpy import pi
from pyqpanda import *

machine = DensityMatrixSimulator()
machine.init_qvm()

q = machine.qAlloc_many(2)
c = machine.cAlloc_many(2)

prog = QProg()
prog.insert(H(q[0]))\
    .insert(Y(q[1]))\
    .insert(RY(q[0], pi / 3))\
    .insert(RX(q[1], pi / 6))\
    .insert(RX(q[1], pi / 9))\
    .insert(CZ(q[0], q[1]))

# 获取对应量子程序的密度矩阵
print(machine.get_density_matrix(prog))

# 获取对应量子程序的在指定量子比特下的约化密度矩阵
print(machine.get_reduced_density_matrix(prog, [0]))

# 获取对应量子程序指定量子态的概率
print("quantum state 00 probability : ", machine.get_probability(prog, "00"))

# 获取对应量子程序所有量子态的概率分布
print(machine.get_probabilities(prog))

# 获取对应量子程序指定哈密顿量下演化的期望值
operator = 0.23 * x(1) + 0.2 * y(1) + 1.6 * z(0)
expval = machine.get_expectation(prog,operator.to_hamiltonian(False),[0, 1])
print(expval)

# 设置噪声模型和参数
machine.set_noise_model(NoiseModel.BITFLIP_KRAUS_OPERATOR, GateType.HADAMARD_GATE, 0.3)
machine.set_noise_model(NoiseModel.BITFLIP_KRAUS_OPERATOR, GateType.CZ_GATE, 0.3)

# 获取加入噪声后,密度矩阵信息和概率分布
print(machine.get_density_matrix(prog))
print(machine.get_probabilities(prog))

machine.finalize()

输出结果如下:

# 对应量子程序的密度矩阵
[[ 0.01196435+0.j  0.04465155+0.j  0.-0.02565762j  1.+0.09575556j]
[ 0.04465155+0.j   0.16664185+0.j  0.-0.09575556j  1.+0.35736463j]
[ 0.+0.02565762j   0.+0.09575556j  0.05502295+0.j -0.20534845+0.j]
[-0.-0.09575556j  -0.-0.3573646j  -0.20534845+0.j  0.76637085-0.j]]

# 对应量子程序的在指定量子比特下的约化密度矩阵
[[ 0.0669873+0.j -0.1606969+0.j]
[-0.1606969+0.j  0.9330127+0.j]]

# 对应量子程序指定量子态的概率
quantum state 00 probability :  0.01196434643886035

# 对应量子程序所有量子态的概率分布
[0.01196434643886035, 0.1666418487178699, 0.05502295166892035, 0.7663708531743493]

# 对应量子程序指定哈密顿量下演化的期望值
-1.5183234356888893

# 加入噪声后,密度矩阵信息
[[ 0.12138551+0.j  -0.03034845+0.j  0.+0.03569962j 1.+0.03830222j]
[-0.03034845+0.j  0.25005696+0.j  0.-0.03830222j 1.+0.09698317j]
[ 0.-0.03569962j  0.+0.03830222j  0.2054094 +0.j -0.13034845+0.j]
[ 0.-0.03830222j  0.-0.09698317j -0.13034845+0.j 0.42314812+0.j]]

# 加入噪声后,概率分布
[0.12138551462195893, 0.25005696344073314, 0.20540940462115326, 0.4231481173161546]

除此之外,密度矩阵的噪声可以叠加,参考下面的一个简单的例子,对于如下的简单线路

from numpy import pi
from pyqpanda import *

machine = DensityMatrixSimulator()
machine.init_qvm()

prog = QProg()
q = machine.qAlloc_many(2)
c = machine.cAlloc_many(2)

prog.insert(X(q[0]))\
    .insert(CNOT(q[0], q[1]))

density_matrix1 = machine.get_density_matrix(prog)

print(density_matrix1)

当我们同时对所有X门设置触发两次比特翻转噪声时,密度矩阵的演化如下:

machine.set_noise_model(NoiseModel.BITFLIP_KRAUS_OPERATOR, GateType.PAULI_X_GATE, 0.3)
print(machine.get_density_matrix(prog))

machine.set_noise_model(NoiseModel.BITFLIP_KRAUS_OPERATOR, GateType.PAULI_X_GATE, 0.3)
print(machine.get_density_matrix(prog))

运行结果如下:

# 第一次施加的噪声
[[0.3+0.j 0. +0.j 0. +0.j 0. +0.j]
[0. +0.j 0. +0.j 0. +0.j 0. +0.j]
[0. +0.j 0. +0.j 0. +0.j 0. +0.j]
[0. +0.j 0. +0.j 0. +0.j 0.7+0.j]]

# 噪声再次叠加的结果
[[0.42+0.j 0. +0.j 0. +0.j 0. +0.j]
[0. +0.j 0. +0.j 0. +0.j 0. +0.j]
[0. +0.j 0. +0.j 0. +0.j 0. +0.j]
[0. +0.j 0. +0.j 0. +0.j 0.58+0.j]]

稳定器与Clifford模拟器



叠加和纠缠 都是量子优势的典型来源,但是当系统包含的量子比特个数N增加时,量子态系数的个数随N指数增加,将无法使用经典计算机实现传统的全振幅模拟,这一问题称为 指数墙问题

基于 Gottesman_knill定理 ,我们可以得知,在基于特定门集形成的稳定器线路中,我们是可以通过多项式复杂度进行模拟的,而这也意味着,可以在某些特定逻辑门构造的线路中打破量子的指数级加速霸权,将经典模拟应用到量子线路中,从而验证量子计算机的结果是否正确。并且在未来的容错量子计算机中,必然是需要冗余信息进行编码,从而达到容错计算的可能,这显然在基于目前量子计算模拟框架中是无法实现大比特线路的。

我们可以另辟蹊径,通过 stabilizer 及对应的 Clifford 门集模拟器可以有效利用其多项式模拟的特性,解决基于pauli噪声的容错量子计算。同时,为了推广到通用量子计算,也可以将stabilizer的理论性质带入到 Clifford+T 的模拟中,基于 Clifford+T 的模拟器,我们可以解决大比特下的non-clifford逻辑门较少前提下的量子模拟(Clifford+T可以近似分解任意逻辑门)。


对于一个量子态 \(|\psi\rangle\) (一般指纯态),如果存在一个酉矩阵U使得 \(U|\psi\rangle = |\psi\rangle\) ,那么称 \(|\psi\rangle\) 可以被U所stabilize,U是 \(|\psi\rangle\) 的一个stabilizer,比如 \(Z|0\rangle = |0\rangle\)

很明显,一个量子态存在多个stabilizer,当有多个stabilizer时,这些stabilizer的乘积自然也是stabilizer。

\(Z_{1}Z_{2}X_{1}X_{2}|\psi\rangle = Z_{1}Z_{2}|\psi\rangle = |\psi\rangle\)

这种乘法封闭性告诉我们stabilizer会形成一个

对于量子态 \(|\psi\rangle\) ,若幺正变换群S中的每个元素都是 \(|\psi\rangle\) 的stabilizer,则称整个幺正变换群S是 \(|\psi\rangle\) 的stabilizer group。

一般情况下我们只关注 \(P\text{auli}\) 矩阵 \(\left\{ X,Y,Z,I \right\}\) 作为stabilizer的情况,即 幺正变换群由Pauli群构成,即

\(Stab(|\psi\rangle) = \left\{ P \in \mathcal{P}_{n}:P|\psi\rangle = |\psi\rangle \right\}\)

上述式子中,Pauli群 \(\mathcal{P}_{n}\) 定义为作用在n比特上的 \(P\text{auli}\) 操作符的集合,其中相位系数为 \(\pm 1\)\(\pm i\)

\(\mathcal{P}_{n} = \left\{ i^{\gamma}X(a)Z(b):\gamma \in \{ 0,1,2,3\},a,b \in \{ 0,1\}^{n} \right\}\)

该Pauli群中 \(P^{(1)},\ldots,P^{(m)} \in \mathcal{P}_{n}\) 各个元素均是独立的。那么我们依据Pauli群的特殊性质可以得到:

\(\begin{matrix} \text{Stab}(|00\rangle)\& = \left\{ I,Z_{1},Z_{2},Z_{1}Z_{2} \right\}\& = \left\langle Z_{1},Z_{2} \right\rangle \\ \text{Stab}(| + + \rangle)\& = \left\{ I,X_{1},X_{2},X_{1}X_{2} \right\}\& = \left\langle X_{1},X_{2} \right\rangle \\ \text{Stab}\left( \frac{\left| 00 \right\rangle + \left| 11 \right\rangle}{\sqrt{2}} \right)\& = \left\{ I,X_{1}X_{2},Z_{1}Z_{2}, - Y_{1}Y_{2} \right\}\& = \ \left\langle X_{1}X_{2},Z_{1}Z_{2} \right\rangle \\ \text{Stab}\left( \left| 0^{n} \right\rangle \right)\& = \left\{ Z(a):a \in \{ 0,1\}^{n} \right\}\& = \left\langle Z_{1},\ldots,Z_{n} \right\rangle \\ \end{matrix}\)

问题在于如何构造 Stabilizer Group ,这里就不得不提到,当 Cliffford Group 门集中的元素作用在Pauli群上会有这样一组变换:

\(\mathbf{P|\psi\rangle = |\psi\rangle \Longleftrightarrow}\left( \mathbf{\text{UP}}\mathbf{U}^{\mathbf{\dagger}} \right)\mathbf{U|\psi\rangle = U|\psi\rangle}\)

当我们将群写成形式 \(P = i^{\gamma}X(a)Z(b)\)Cliffford Group 的作用形式如下:

\(U_{j}PU_{j}^{\dagger} = i^{\gamma}X^{a_{1}}Z^{b_{1}} \otimes \ldots \otimes X^{a_{j - 1}}Z^{b_{j - 1}} \otimes UX^{a_{j}}Z^{b_{j}}U^{\dagger} \otimes X^{a_{j + 1}}Z^{b_{j + 1}} \otimes \ldots \otimes X^{a_{n}}Z^{b_{n}}\)

我们会惊讶的发现, \(\mathbf{U}_{\mathbf{j}}\mathbf{P}\mathbf{U}_{\mathbf{j}}^{\mathbf{\dagger}}\mathbf{=}\mathbf{P}_{\mathbf{\text{new}}}\) 。也就如下图所示:

_images/clifford.png

这里可以发现,我们将 \(\mathcal{P}_{n}\) 中的Y的变换去除了,这是由于 \(Y = IXZ\)

\(|\psi\rangle \rightarrow U|\psi\rangle\)

等价的只需要追踪stabilizer的演化,同样可以得到系统完整的动力学信息。

\(S \rightarrow USU^{\dagger}\)

这里将量子态的逻辑门演化问题转化为更新量子态对应的 Stabilizer Group 问题,即使用 Stabilizer 模拟量子线路的核心思想是使用 Stabilizer Group 表征量子态,而不是传统模拟器的振幅。

也就是说,在基于特定门集形成的稳定器线路中,根据线路特性,通过多项式复杂度即可进行模拟超大数量的量子线路 (仅限由Clifford量子逻辑门集合和衍生集合组成:H, S, X, Y, Z, CNOT, CY, CZ, SWAP )


pyqpanda 中可以通过 Stabilizer 类实现对大比特的Clifford线路模拟,和许多其他模拟器有类似的功能接口:

class Stabilizer(QuantumMachine)

基于Stablizer,模拟基本的Clifford量子线路的模拟器。

变量:
  • _noise_model (NoiseModel) -- 噪声模型,用于模拟实际量子系统中的噪声。

  • _noise_set (bool) -- 是否已设置噪声模型。

__init__()

构造函数,初始化 Stabilizer 类的实例。

init_qvm()

初始化Stablizer。

prob_run_dict(qprog: QProg, qubits: QVec, select_max: int = -1) Dict[str, float]

运行量子程序并获取概率结果。

参数:
  • qprog (QProg) -- 要运行的量子程序。

  • qubits (QVec) -- 用于测量的量子比特。

  • select_max (int, optional) -- 最大选择数(默认为 -1 表示不限制)。

返回:

量子程序的概率结果。

返回类型:

Dict[str, float]

run_with_configuration(qprog: QProg, shot: int) Dict[str, int]

运行量子程序并获取测量结果。

参数:
  • qprog (QProg) -- 要运行的量子程序。

  • shot (int) -- 测量次数。

返回:

量子程序的测量结果。

返回类型:

Dict[str, int]

set_noise_model(noise_model: NoiseModel, gate_types: GateType | List[GateType], prob: float, target_qubits: QVec | List[QVec] | None = None) None

设置噪声模型,用于模拟实际量子系统中的噪声。

参数:
  • noise_model (NoiseModel) -- 噪声模型。

  • gate_types (Union[GateType, List[GateType]]) -- 受噪声影响的门类型或门类型列表。

  • prob (float) -- 噪声发生的概率。

  • target_qubits (Optional[Union[QVec, List[QVec]]]) -- 受噪声影响的目标量子比特或目标量子比特列表(可选)。

返回:

无返回值。

返回类型:

None

此函数允许您设置用于模拟实际量子系统中噪声的噪声模型,以及受影响的门类型和概率。可以选择指定受影响的目标量子比特,目前支持的噪声模型如下:
  • bit-flip :比特翻转噪声模型,按指定概率发生X方向错误

  • phase-flip :相位翻转噪声模型,按指定概率发生Y方向错误

  • bit-phase-flip :比特相位翻转噪声模型,按指定概率发生Z方向错误

  • phase-damping :相位阻尼噪声模型,相位阻尼可转化为相位反转噪声模型

  • depolarizing :去极化噪声模型,X,Y和Z三个方向上发生等概率错误


from numpy import pi
from pyqpanda import *

# 初始化Clifford模拟器,默认最大支持6000比特
machine = Stabilizer()
machine.init_qvm()

q = machine.qAlloc_many(100)
c = machine.cAlloc_many(100)

# 构建量子线路,支持的门集为{ H, S, X, Y, Z, CNOT, CY, CZ, SWAP }
prog = QProg()
prog.insert(X(q[1]))\
    .insert(H(q[2]))\
    .insert(H(q[49]))\
    .insert(Z(q[2]))\
    .insert(CZ(q[0], q[22]))\
    .insert(CNOT(q[2], q[39]))\
    .insert(measure_all(q, c))\

# run_with_configuration用于获取测量操作的测量结果
result = machine.run_with_configuration(prog, 1000)
print(result)

machine.finalize()

输出结果如下:

{'000000000000000000000000000000000000000000000000000000000010': 254,
 '000000000000000000001000000000000000000000000000000000000110': 279,
 '000000000010000000000000000000000000000000000000000000000010': 251,
 '000000000010000000001000000000000000000000000000000000000110': 216}

from numpy import pi
from pyqpanda import *

# 初始化Clifford模拟器,默认最大支持6000比特
machine = Stabilizer()
machine.init_qvm()

q = machine.qAlloc_many(100)
c = machine.cAlloc_many(100)

# 构建量子线路,支持的门集为{ H, S, X, Y, Z, CNOT, CY, CZ, SWAP }
prog = QProg()
prog.insert(X(q[1]))\
    .insert(H(q[0]))\
    .insert(H(q[1]))\
    .insert(Z(q[99]))\
    .insert(CZ(q[0], q[22]))\
    .insert(CNOT(q[2], q[98]))\

# prob_run_dict用于获取指定比特的测量结果
result = machine.prob_run_dict(prog, [q[0],q[1],q[2]])
print(result)

machine.finalize()

输出结果如下:

{'000': 0.25, '001': 0.25, '010': 0.25, '011': 0.25, '100': 0.0, '101': 0.0, '110': 0.0, '111': 0.0}

本源量子云服务

在复杂的量子线路模拟中有必要借助于高性能计算机集群或真实的量子计算机,用云计算的方式替代本地计算,在一定程度上减轻用户的计算成本,获得更好的计算体验。

本源量子量子云平台经过本源司南服务向部署在远程的量子计算机或计算集群提交任务,并接收返回的结果,流程如下图所示。

_images/qcloud.png

pyqpanda封装了多种量子计算服务,可以向本源量子的计算服务器集群或量子真实芯片发送计算指令,并获取计算结果,具体见下图。

_images/2024cloud.png

高性能计算集群云服务

当涉及到处理复杂的量子计算和模拟任务时,高性能计算集群成为了不可或缺的工具。

与个人电脑的单进程计算方式不同,高性能计算集群采用分布式计算算法,意味着计算任务可以被分解成多个子任务,并在集群中的多个计算节点上并行执行,从而大大提升了计算效率和速度。这对于处理复杂的量子计算任务尤为重要,因为量子线路模拟往往涉及大量的计算和存储需求。通过分布式计算,我们能够将这些庞大的计算任务分解成更小的部分,在多个节点上同时进行处理,从而显著缩短了计算时间。

本源量子的高性能计算集群提供多种功能强大的虚拟机计算后端,针对不同的量子计算模型和算法进行了优化,适用于不同情况下的量子线路模拟需求,我们引入 QCloud 来提交任务和查询计算计算结果。

class QCloud(QuantumMachine)

量子云计算集群任务管理类,用于管理集群计算,提交任务并获取结果。

参数:

None (None) -- 无参数。

__init__()

创建一个 Quantum Cloud 虚拟机实例。

返回:

无返回值。

返回类型:

None

full_amplitude_measure(prog, shot, task_name='QPanda Experiment')

对给定量子线路执行全振幅采样测量,返回测量结果的概率分布。

参数:
  • prog (QProg) -- 要执行的量子线路。

  • shot (int) -- 测量的次数。

  • task_name (str, optional) -- 任务名称,默认为 'QPanda Experiment'。

返回:

各测量结果的概率分布。

返回类型:

Dict[str, float]

full_amplitude_pmeasure(prog, qvec, task_name='QPanda Experiment')

对给定量子线路执行全振幅概率测量,测量结果只考虑指定的测量比特,返回测量结果的概率分布。

参数:
  • prog (QProg) -- 要执行的量子线路。

  • qvec (List[int]) -- 指定的测量比特列表。

  • task_name (str, optional) -- 任务名称,默认为 'QPanda Experiment'。

返回:

各测量结果的概率分布。

返回类型:

Dict[str, float]

get_expectation(prog, hamiltonian, qvec, task_name='QPanda Experiment')

该方法在给定的量子线路下,根据指定的哈密顿量,计算量子态的期望值。

参数:
  • prog (QProg) -- 要执行的量子线路。

  • hamiltonian (List[Tuple[Dict[int, str], float]]) -- 哈密顿量的项和系数组成的列表。

  • qvec (QVec) -- 用于计算期望值的量子比特列表。

  • task_name (str, optional) -- 任务名称,默认为 'QPanda Experiment'。

返回:

计算得到的期望值。

返回类型:

float

init_qvm(token, is_logged=False)

初始化量子虚拟机。

参数:
  • token (str) -- 访问云服务所需的用户标识。

  • is_logged (bool, optional) -- 是否输出日志,默认为 False。

返回:

无返回值。

返回类型:

None

noise_measure(prog, shot, task_name='QPanda Experiment')

对给定量子线路执行带噪声的测量,返回测量结果的概率分布,需要提前设置噪声模型和参数

参数:
  • prog (QProg) -- 要执行的量子线路。

  • shot (int) -- 测量的次数。

  • task_name (str, optional) -- 任务名称,默认为 'QPanda Experiment'。

返回:

各测量结果的概率分布。

返回类型:

Dict[str, float]

partial_amplitude_pmeasure(prog, amp_vec, task_name='QPanda Experiment')

对给定量子线路执行部分振幅测量,返回测量结果的概率幅值分布。

参数:
  • prog (QProg) -- 要执行的量子线路。

  • amp_vec (List[str]) -- 部分振幅测量的振幅向量。

  • task_name (str, optional) -- 任务名称,默认为 'QPanda Experiment'。

返回:

各测量结果的概率幅值分布。

返回类型:

Dict[str, complex]

set_noise_model(arg0, arg1, arg2)

该方法用于设置量子虚拟机的噪声模型,包括噪声模型本身和相关的噪声参数。

参数:
  • arg0 (NoiseModel) -- 噪声模型。

  • arg1 (List[float]) -- 噪声参数列表。

  • arg2 (List[float]) -- 噪声参数列表。

返回:

无返回值。

返回类型:

None

single_amplitude_pmeasure(prog, amplitude, task_name='QPanda Experiment')

对给定量子线路执行单振幅测量,返回测量结果的概率幅值。

参数:
  • prog (QProg) -- 要执行的量子线路。

  • amplitude (str) -- 单振幅测量的振幅。

  • task_name (str, optional) -- 任务名称,默认为 'QPanda Experiment'。

返回:

测量结果的概率幅值。

返回类型:

complex

我们以简单的量子线路为例,导入必要的库,然后是初始化和设置用户信息过程,用户可以在本源量子云官网 QCloud_免费注册获取用户标识符,参考 真实芯片计算服务 章节内容

from pyqpanda import *
import numpy as np

# 通过QCloud()创建量子云虚拟机
QCM = QCloud()

# 通过传入当前用户的token来初始化
QCM.init_qvm("608e020100301006072a8648ce3d020106052b8104001c041730150201010410634a5b6d0a2a9a2b03b9d7c17c57405f/13082")

然后是构建量子线路,对于需要采样测量的量子线路需要插入测量节点

qlist = QCM.qAlloc_many(6)
clist = QCM.cAlloc_many(6)

measure_prog = QProg()
measure_prog << hadamard_circuit(qlist)\
             << CZ(qlist[1], qlist[5])\
             << Measure(qlist[0], clist[0])\
             << Measure(qlist[1], clist[1])

pmeasure_prog = QProg()
pmeasure_prog << hadamard_circuit(qlist)\
              << CZ(qlist[1], qlist[5])\
              << RX(qlist[2], np.pi / 4)\
              << RX(qlist[1], np.pi / 4)\

接下来就是提交计算任务和获取结果:

  • full_amplitude_measure(全振幅蒙特卡洛测量操作)

    result0 = QCM.full_amplitude_measure(measure_prog, 100)
    print(result0)
    

    需要传入的第二个参数是测量次数,输出结果如下,左侧是量子态的二进制表示,右边表示测量次数对应的概率:

    {'00': 0.263,
     '01': 0.255,
     '10': 0.241,
     '11': 0.241}
    
  • full_amplitude_pmeasure(全振幅概率测量操作)

    result1 = QCM.full_amplitude_pmeasure(pmeasure_prog, [0, 1, 2])
    print(result1)
    

    需要传入的第二个参数是测量的比特,输出结果如下,左侧是量子态的二进制表示,右边表示测量对应的概率:

    {'000': 0.12499999999999988,
     '001': 0.12499999999999988,
     '010': 0.12499999999999988,
     '011': 0.12499999999999988,
     '100': 0.12499999999999988,
     '101': 0.12499999999999988,
     '110': 0.12499999999999988,
     '111': 0.12499999999999988}
    
  • partial_amplitude_pmeasure(部分振幅概率测量操作)

    result2 = QCM.partial_amplitude_pmeasure(pmeasure_prog, ["0", "1", "2"])
    print(result2)
    

    需要传入的第二个参数是测量的量子态振幅的十进制表示,输出结果如下,左侧是量子态振幅的十进制表示,右边表示复数形式的振幅值:

    {'0': (0.08838832192122936-0.08838833495974541j),
     '1': (0.08838832192122936-0.08838833495974541j),
     '2': (0.08838832192122936-0.08838833495974541j)}
    
  • single_amplitude_pmeasure(单振幅概率测量操作)

    result3 = QCM.single_amplitude_pmeasure(pmeasure_prog, "0")
    print(result3)
    

    需要传入的第二个参数是测量的振幅(十进制表示),输出结果如下,只会输出一个量子态对应的复数形式的振幅值:

    (0.08838833056846361-0.08838833850593952j)
    
  • noise_measure(噪声虚拟机测量操作)

    QCM.set_noise_model(NoiseModel.BIT_PHASE_FLIP_OPRATOR, [0.01], [0.02])
    result4 = QCM.noise_measure(measure_prog, 100)
    print(result4)
    

    通过 set_noise_model 设置噪声参数,第一个参数是噪声模型,后面分别是单门噪声参数和双门噪声参数,噪声模型的定义如下:

    enum NOISE_MODEL
    {
        DAMPING_KRAUS_OPERATOR,
        DEPHASING_KRAUS_OPERATOR,
        DECOHERENCE_KRAUS_OPERATOR_P1_P2,
        BITFLIP_KRAUS_OPERATOR,
        DEPOLARIZING_KRAUS_OPERATOR,
        BIT_PHASE_FLIP_OPRATOR,
        PHASE_DAMPING_OPRATOR,
        DECOHERENCE_KRAUS_OPERATOR,
        PAULI_KRAUS_MAP,
        KRAUS_MATRIX_OPRATOR,
        MIXED_UNITARY_OPRATOR,
    };
    

    可以通过pyqpanda的枚举类 NoiseModel 来获取,该接口输出结果如下,左侧是量子态的二进制表示,右边表示测量对应的概率:

    {'00': 0.27,
     '01': 0.22,
     '10': 0.21,
     '11': 0.30}
    

真实芯片计算服务


本源悟空超导芯片

本源悟空 是2024年本源量子正式发布的新一代超导量子计算机,最大运行规模可达72比特,并且在量子计算纠错,运行速度上实现质的飞跃。

对于芯片任务,同样是通过 QCloud 来提交任务和查询计算计算结果。

用户首先需要通过 注册并访问 最新的本源量子云计算官网 本源量子云

然后点击右上键的 工作台 ,进入量子计算访问计算界面,

_images/2024cloud.png

可以看到有各种计算服务,包括虚拟计算和真实量子计算,接着需要进一步获取 api_token 等相关信息。 api_token 是每个用户用于使用pyqpanda的计算接口访问量子云计算资源的标识符,可以在个人账号中心获取。

_images/token.png

api_token 是重要的量子计算资源访问凭证,请妥善保管,量子计算任务的提交和查询,需要通过pyqpanda的量子云组件 QCloud ,通过将 api_token 作为 QCloud 的初始化函数 init_qvm 的参数传递,就可以正常使用后续接口,示例如下:

machine = QCloud()
machine.set_configure(72,72);

machine.init_qvm("502e0201003016072ce3d020106052b8101c04150201010410b6d33ad8772eb9705e844394453a3c8a/6327",False)

量子云组件 QCloud 的其他接口介绍如下:

class QCloud(QuantumMachine)

除了用于与远程计算集群交互, QCloud 也可以通过提交真实量子计算机芯片任务并获取结果。

参数:

QuantumMachine (class) -- QuantumMachine类的基类。

变量:

machine (origin quantum cloud) -- 该类用于管理远程量子云计算资源。

__init__()

QCloud类的构造函数。

返回:

无返回值

返回类型:

None

get_state_fidelity(prog, shot, chip_id=2, is_amend=True, is_mapping=True, is_optimization=True, task_name='QPanda Experiment')

该方法将给定的量子线路提交到远程真实量子芯片上进行计算,然后返回计算得到的状态保真度。可以通过调整参数来控制计算的方式和行为。

参数:
  • prog (QProg) -- 要计算状态保真度的量子线路。

  • shot (int) -- 重复运行线路以计算期望值的次数。

  • chip_id (int, optional) -- 远程计算集群上的芯片ID,正确默认为2(本源悟源芯片5号)。

  • is_amend (bool, optional) -- 是否开启读取保真度修正。

  • is_mapping (bool, optional) -- 是否进行电路映射。

  • is_optimization (bool, optional) -- 是否进行优化。

  • task_name (str, optional) -- 任务名称,默认为'QPanda Experiment'。

返回:

计算得到的状态保真度。

返回类型:

float

get_state_tomography_density(prog, shot, chip_id=2, is_amend=True, is_mapping=True, is_optimization=True, task_name='QPanda Experiment')

计算量子线路的qst层析结果。

参数:
  • prog (QProg) -- 要计算态密度矩阵的量子线路。

  • shot (int) -- 重复运行线路以计算期望值的次数。

  • chip_id (int, optional) -- 远程计算集群上的芯片ID,正确默认为2(本源悟源芯片5号)。

  • is_amend (bool, optional) -- 是否开启读取保真度修正。

  • is_mapping (bool, optional) -- 是否进行电路映射。

  • is_optimization (bool, optional) -- 是否进行优化。

  • task_name (str, optional) -- 任务名称,默认为'QPanda Experiment'。

返回:

计算得到的态密度矩阵。

返回类型:

List[List[complex]]

init_qvm(token: str, is_logged: bool = False, use_bin_or_hex: bool = True, enable_pqc_encryption=False, request_time_out: int = 100)

该方法用于初始化 QVM 服务,提供必要的用户身份验证令牌和其他参数。可选参数用于配置 QVM 的行为,例如是否记录操作,以及在处理二进制和十六进制字符串时是否使用默认设置。

参数:
  • token (str) -- 用户身份验证令牌。

  • is_logged (bool, optional) -- 是否在控制台上记录 QVM 操作(默认为 False)。

  • use_bin_or_hex (bool, optional) -- 是否在处理二进制和十六进制字符串时使用默认设置(默认为 True)。

  • enable_pqc_encryption -- 是否启用混合加密算法对数据传输进行加密(默认为 False)

  • request_time_out (int, optional) -- 请求超时时间,以秒为单位(默认为 100)。

real_chip_measure(prog, shot, chip_id=2, is_amend=True, is_mapping=True, is_optimization=True, task_name='QPanda Experiment')

在真实量子计算芯片上进行量子测量。

参数:
  • prog (Union[QProg, str]) -- 要在实际芯片上测量的量子线路。

  • shot (int) -- 重复运行线路以计算期望值的次数。

  • chip_id (int, optional) -- 实际芯片ID,正确默认为2(本源悟源芯片5号)。

  • is_amend (bool, optional) -- 是否开启读取保真度修正,默认为True。

  • is_mapping (bool, optional) -- 是否进行电路映射,默认为True。

  • is_optimization (bool, optional) -- 是否进行优化,默认为True。

  • task_name (str, optional) -- 任务名称,默认为'QPanda Experiment'。

返回:

测量结果字典,包含各个测量结果的概率。

返回类型:

Dict[str, float]

async_real_chip_measure(prog, shot, chip_id=2, is_amend=True, is_mapping=True, is_optimization=True, task_name='QPanda Experiment')

异步在真实量子计算芯片上进行量子测量,后续查询计算结果需要配合query_task_state_result使用

参数:
  • prog (Union[QProg, str]) -- 要在实际芯片上测量的量子线路。

  • shot (int) -- 重复运行线路以计算期望值的次数。

  • chip_id (int, optional) -- 实际芯片ID,默认为2(本源悟源芯片5号)。

  • is_amend (bool, optional) -- 是否开启读取保真度修正,默认为True。

  • is_mapping (bool, optional) -- 是否进行电路映射,默认为True。

  • is_optimization (bool, optional) -- 是否进行优化,默认为True。

  • task_name (str, optional) -- 任务名称,默认为'QPanda Experiment'。

返回:

测量结果字典,包含各个测量结果的概率。

返回类型:

Dict[str, float]

async_batch_real_chip_measure(prog_array, shot, chip_id=real_chip_type.origin_72, is_amend=True, is_mapping=True, is_optimization=True)

在真实量子计算芯片上批量进行量子测量,后续查询计算结果需要配合query_batch_task_state_result使用

参数:
  • prog_array (Union[List[QProg], List[str]]) -- 要执行的量子程序列表。

  • shot (int) -- 每个程序执行的次数(测量次数)。

  • chip_id (real_chip_type, optional) -- 要使用的真实量子芯片的ID,默认为 real_chip_type.origin_72。

  • is_amend (bool, optional) -- 是否对程序执行修正,默认为True。

  • is_mapping (bool, optional) -- 是否进行量子比特映射,默认为True。

  • is_optimization (bool, optional) -- 是否进行门融合优化,默认为True。

返回:

批量任务ID。

返回类型:

str

batch_real_chip_measure(prog_array, shot, chip_id=real_chip_type.origin_72, is_amend=True, is_mapping=True, is_optimization=True)

在真实量子计算芯片上批量进行量子测量。

参数:
  • prog_array (Union[List[QProg], List[str]]) -- 要执行的量子程序列表。

  • shot (int) -- 每个程序执行的次数(测量次数)。

  • chip_id (real_chip_type, optional) -- 要使用的真实量子芯片的ID,默认为 real_chip_type.origin_72。

  • is_amend (bool, optional) -- 是否对程序执行修正,默认为True。

  • is_mapping (bool, optional) -- 是否进行量子比特映射,默认为True。

  • is_optimization (bool, optional) -- 是否进行门融合优化,默认为True。

返回:

包含每个程序测量结果概率的字典列表。

返回类型:

List[Dict[str, float]]

query_task_state_result(task_id: str)

该方法用于查询单个任务的状态和结果。如果任务成功完成,结果列表将包含任务状态和相应的测量结果或其他相关信息。

参数:

task_id (str) -- 要查询的任务ID。

返回:

包含任务状态和结果的列表。如果任务成功完成,结果将包含状态和相应的测量结果或其他相关信息。

返回类型:

List[Union[int, Any]]

query_batch_task_state_result(task_id: str)

该方法用于查询批量任务的状态和结果。如果批量任务成功完成,结果列表将包含任务状态和相应的测量结果或其他相关信息。

参数:

task_id (str) -- 要查询的批量任务ID。

返回:

包含任务状态和结果的列表。如果批量任务成功完成,结果将包含状态和相应的测量结果或其他相关信息。

返回类型:

List[Union[int, List[Any]]]

通过量子云平台向本源悟源请求计算任务的完整代码流程如下:

from pyqpanda import *

# 通过QCloud()创建量子云虚拟机
qm = QCloud()

# 通过传入当前用户的token来初始化,需要确保当前用户有足够算力资源
qm.init_qvm("302e02010001006072a8648ce3d020106052b810400104173015020100410634a5b6d0a2a9a2b03b9d7c17c57405f/13082")

qlist = qm.qAlloc_many(6)
clist = qm.cAlloc_many(6)

# 构建量子程序,可以手动输入,也可以来自OriginIR或QASM语法文件等
prog = QProg()
prog << hadamard_circuit(qlist)\
    << CZ(qlist[1], qlist[5])\
    << Measure(qlist[0], clist[0])\
    << Measure(qlist[1], clist[1])

# 调用真实芯片计算接口,至少需要量子程序和测量次数两个参数
result = qm.real_chip_measure(prog, 1000, real_chip_type.origin_72)
print(result)
qm.finalize()

real_chip_type.origin_72 表示使用最新的悟空72比特芯片

在使用本源真实芯片计算服务时,经常会遇到各种错误,下面给出部分错误信息,可以根据抛出的错误异常信息进行对号入座。

  • server connection failed :该异常表示服务器宕机或与服务器连接失败

  • api key error :该异常表示用户的API-Key参数异常,请去官网确认个人资料的信息

  • un-activate products or lack of computing power :该异常表示用户未开通该产品或算力不足

  • build system error :该异常表示编译系统运行出错

  • exceeding maximum timing sequence :该异常表示量子程序时序过长

  • unknown task status :其他任务状态异常的情况

除了蒙特卡洛测量接口之外,还有用于获取 量子态qst层析 结果和 保真度 接口,下面逐一介绍:

  • 获取量子态qst层析结果接口: get_state_tomography_density ,使用示例如下:

from pyqpanda import *
PI=3.14159

qm = QCloud()
qm.set_configure(72,72);

qm.init_qvm("302e020100301006072a88ce3d020106052b81040041730150201010410b6d33ad87729705e844394453a3c8a/65327",True)

q = qm.qAlloc_many(6)
c = qm.cAlloc_many(6)

prog = QProg()
prog << hadamard_circuit(q)\
    << RX(q[1], PI / 4)\
    << RX(q[2], PI / 4)\
    << RX(q[1], PI / 4)\
    << CZ(q[0], q[1])\
    << CZ(q[1], q[2])\
    << Measure(q[0], c[0])\
    << Measure(q[1], c[1])

result = qm.get_state_tomography_density(prog, 1000,real_chip_type.origin_72)
print(result)
qm.finalize()

输出结果是测量的两比特的QST层析结果,参考结果如下

[[(0.2595032944754182+0j), (0.21819564115560064+0.01368474404460212j), (0.0010136847440446045-0.008616320324379118j), (0.020273694880892028+0.01951343132285857j)],
[(0.21819564115560064-0.01368474404460212j), (0.26001013684744045+0j), (0.000760263558033443+0.011657374556512917j), (-0.008362899138367963+0.010897110998479481j)],
[(0.0010136847440446045+0.008616320324379118j), (0.000760263558033443-0.011657374556512917j), (0.2554485554992397+0j), (-0.21490116573745568+0.012417638114546374j)],
[(0.020273694880892028-0.01951343132285857j), (-0.008362899138367963-0.010897110998479481j), (-0.21490116573745568-0.012417638114546374j), (0.22503801317790167+0j)]]
  • 获取量子态保真度接口: get_state_fidelity ,使用示例如下:

from pyqpanda import *
PI=3.14159

qm = QCloud()
qm.set_configure(72,72);

qm.init_qvm("302e020100301006072a868ce3d02006052b8104001c041730502010424100b6d33ad8772eb9705e844394453a3c8a/16327",True)

q = qm.qAlloc_many(6)
c = qm.cAlloc_many(6)

prog = QProg()
prog << hadamard_circuit(q)\
    << RX(q[1], PI / 4)\
    << RX(q[2], PI / 4)\
    << RX(q[1], PI / 4)\
    << CZ(q[0], q[1])\
    << CZ(q[1], q[2])\
    << Measure(q[0], c[0])\
    << Measure(q[1], c[1])

result = qm.get_state_fidelity(prog, 1000,real_chip_type.origin_72)
print(result)
qm.finalize()

输出结果是保真度,参考结果如下

0.928951

同时支持批量任务提交接口,分为**同步**和**异步**两种:

  • 1.同步批量任务提交接口:batch_real_chip_measure 接口会一直等待结果返回,使用示例如下:

from pyqpanda import *

machine = QCloud()
machine.set_configure(72,72);

# XXX替换为实际用户api_token,可以从本源量子计算官网 https://qcloud.originqc.com.cn/ 获取
machine.init_qvm("XXX", False)

qlist = machine.qAlloc_many(6)
clist = machine.cAlloc_many(6)

measure_prog = QProg()
measure_prog << H(qlist[0])\
            << CNOT(qlist[0], qlist[1])\
            << CNOT(qlist[1], qlist[2])\
            << Measure(qlist[0], clist[0])\
            << Measure(qlist[1], clist[1])\
            << Measure(qlist[2], clist[2])

batch_prog = [measure_prog for _ in range (6)]

pmeasure_prog = QProg()
pmeasure_prog << H(qlist[0])\
            << CNOT(qlist[0], qlist[1])\
            << CNOT(qlist[1], qlist[2])

originir_list = [convert_qprog_to_originir(prog, machine) for prog in batch_prog]

real_chip_measure_batch_result = machine.batch_real_chip_measure(batch_prog, 1000, real_chip_type.origin_72)
originir_list_result = machine.batch_real_chip_measure(originir_list, 1000, real_chip_type.origin_72)

batch_real_chip_measure 同时支持List[QProg]和List[originir_str]两种参数方式。

  • 2.异步批量任务提交接口:async_batch_real_chip_measure 接口会一直等待结果返回,使用示例如下:

    from pyqpanda import *
    
    machine = QCloud()
    machine.set_configure(72,72);
    
    machine.init_qvm("XXX",True)
    
    qlist = machine.qAlloc_many(6)
    clist = machine.cAlloc_many(6)
    
    measure_prog = QProg()
    measure_prog << hadamard_circuit(qlist)\
                << CZ(qlist[0], qlist[1])\
                << Measure(qlist[0], clist[0])\
                << Measure(qlist[1], clist[1])\
                << Measure(qlist[2], clist[2])
    
    batch_prog = [measure_prog for _ in range (6)]
    
    pmeasure_prog = QProg()
    pmeasure_prog  << hadamard_circuit(qlist)\
                << CZ(qlist[0], qlist[1])
    
    originir_list = [convert_qprog_to_originir(prog, machine) for prog in batch_prog]
    
    batch_id = machine.async_batch_real_chip_measure(originir_list, 1000, real_chip_type.origin_72)
    print(batch_id) # example : '8C3C5BDDA616E1A094B76A85473F3557'
    
    import time
    while(True):
        state, result = machine.query_batch_task_state_result(batch_id)
    
        time.sleep(2)
        if(state == QCloud.TaskStatus.FINISHED.value):
            break
    
    print(state, result)
    

    batch_real_chip_measure 也是同时支持List[QProg]和List[originir_str]两种参数方式,需要配合 query_batch_task_state_result 使用,该接口返回的是元组类型,包含任务状态和结果。

备注

  • 一次批量计算任务的数量最大上限是 200 ,超过这个数值需要拆分成多次提交。

  • 使用前需要确保用户已经开通相关权限,并且有足够的算力资源,否则会出现没有权限或者计算资源不足等出错信息。详见 https://qcloud.originqc.com.cn/zh/computerServices

  • 在使用时遇到任何问题,请给我们提交 用户反馈 ,我们看到后会尽快解决你的问题。

泡利算符类

泡利算符是一组三个2×2的幺正厄米复矩阵,又称酉矩阵。我们一般都以希腊字母 \(\sigma\) (西格玛)来表示,记作 \(\sigma_x\)\(\sigma_y\)\(\sigma_Z\) 。 在 QPanda 中我们称它们为 \(X\) 门,\(Y\) 门,\(Z\) 门。 它们对应的矩阵形式如下表所示。

X
\(\sigma_x\)
\(\begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix}\quad\)
Y
\(\sigma_y\)
\(\begin{bmatrix} 0 & -i \\ i & 0 \end{bmatrix}\quad\)
Z
\(\sigma_z\)
\(\begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix}\quad\)

泡利算符的运算规则如下:

1. 泡利算符与自身相乘得到是单位矩阵

\[\sigma_x\sigma_x = I\]
\[\sigma_y\sigma_y = I\]
\[\sigma_z\sigma_z = I\]

2. 泡利算符与单位矩阵相乘,无论是左乘还是右乘,其值不变

\[\sigma_xI = I\sigma_x = \sigma_x\]
\[\sigma_yI = I\sigma_y = \sigma_y\]
\[\sigma_zI = I\sigma_z = \sigma_z\]

3. 顺序相乘的两个泡利算符跟未参与计算的泡利算符是 \(i\) 倍的关系

\[\sigma_x\sigma_y = i\sigma_z\]
\[\sigma_y\sigma_z = i\sigma_x\]
\[\sigma_z\sigma_x = i\sigma_y\]

4. 逆序相乘的两个泡利算符跟未参与计算的泡利算符是 \(-i\) 倍的关系

\[\sigma_y\sigma_x = -i\sigma_z\]
\[\sigma_z\sigma_y = -i\sigma_x\]
\[\sigma_x\sigma_z = -i\sigma_y\]

模块介绍

class PauliOperator

Pauli 算符类

该类实现了生成和操作 Pauli 算符集合的功能,用于表示量子哈密顿量或量子操作。Pauli 算符是由 Pauli 矩阵组成的线性组合,常用于描述量子系统的演化和能级。

__init__()

初始化 PauliOperator 类实例。

__init__(value: complex)

初始化 PauliOperator 类实例,给定复数值。

参数:

value (complex) -- 复数值。

__init__(matrix: numpy.ndarray, is_reduce_duplicates: bool = False)

初始化 PauliOperator 类实例,给定矩阵表示。

参数:
  • matrix (numpy.ndarray) -- 表示 Pauli 算符的矩阵,要求为 numpy.ndarray[numpy.float64[m, n]] 类型。

  • is_reduce_duplicates (bool, optional) -- 是否进行重复项削减。默认为 False。

__init__(key: str, value: complex, is_reduce_duplicates: bool = False)

初始化 PauliOperator 类实例,给定键值对。

参数:
  • key (str) -- 代表 Pauli 算符的字符串键。

  • value (complex) -- 复数值。

  • is_reduce_duplicates (bool, optional) -- 是否进行重复项削减。默认为 False。

__init__(pauli_map: Dict[str, complex], is_reduce_duplicates: bool = False)

初始化 PauliOperator 类实例,给定 Pauli 算符字典。

参数:
  • pauli_map (Dict[str, complex]) -- 包含 Pauli 算符键值对的字典。

  • is_reduce_duplicates (bool, optional) -- 是否进行重复项削减。默认为 False。

dagger() PauliOperator

返回 Pauli 算符的共轭转置。

返回:

Pauli 算符的共轭转置。

返回类型:

PauliOperator

data() List[Tuple[Tuple[Dict[int, str], str], complex]]

返回 Pauli 算符数据的列表形式。

返回:

包含 Pauli 算符数据的列表,每个元组包含表示和复数值。

返回类型:

List[Tuple[Tuple[Dict[int, str], str], complex]]

error_threshold() float

返回 Pauli 算符的错误阈值。

返回:

Pauli 算符的错误阈值。

返回类型:

float

getMaxIndex() int

返回 Pauli 算符最大索引,下标从0开始

返回:

Pauli 算符最大索引。

返回类型:

int

get_max_index() int

返回 Pauli 算符最大索引,下标从0开始

返回:

Pauli 算符最大索引。

返回类型:

int

isAllPauliZorI() bool

检查是否所有 Pauli 算符都是 Pauli-Z 或单位算符。

返回:

若所有算符均为 Pauli-Z 或单位算符则返回 True,否则返回 False。

返回类型:

bool

isEmpty() bool

检查 Pauli 算符是否为空。

返回:

若 Pauli 算符为空则返回 True,否则返回 False。

返回类型:

bool

is_all_pauli_z_or_i() bool

检查是否所有 Pauli 算符都是 Pauli-Z 或单位算符。

返回:

若所有算符均为 Pauli-Z 或单位算符则返回 True,否则返回 False。

返回类型:

bool

is_empty() bool

检查 Pauli 算符是否为空。

返回:

若 Pauli 算符为空则返回 True,否则返回 False。

返回类型:

bool

reduce_duplicates() None

削减重复的 Pauli 算符项。

remapQubitIndex(remap_dict: Dict[int, int]) PauliOperator

重新映射量子比特索引。

参数:

remap_dict (Dict[int, int]) -- 指定索引映射关系的字典。

返回:

重新映射后的 Pauli 算符。

返回类型:

PauliOperator

remap_qubit_index(remap_dict: Dict[int, int]) PauliOperator

重新映射量子比特索引。

参数:

remap_dict (Dict[int, int]) -- 指定索引映射关系的字典。

返回:

重新映射后的 Pauli 算符。

返回类型:

PauliOperator

setErrorThreshold(threshold: float) None

设置 Pauli 算符的错误阈值。

参数:

threshold (float) -- 错误阈值。

set_error_threshold(threshold: float) None

设置 Pauli 算符的错误阈值。

参数:

threshold (float) -- 错误阈值。

toHamiltonian(sparse: bool) List[Tuple[Dict[int, str], float]]

将 Pauli 算符转换为哈密顿量。

参数:

sparse (bool) -- 是否以稀疏矩阵形式表示哈密顿量。

返回:

哈密顿量数据列表,每个元组包含表示和复数值。

返回类型:

List[Tuple[Dict[int, str], float]]

toString() str

返回 Pauli 算符的字符串表示。

返回:

Pauli 算符的字符串表示。

返回类型:

str

to_hamiltonian(sparse: bool) List[Tuple[Dict[int, str], float]]

将 Pauli 算符转换为哈密顿量。

参数:

sparse (bool) -- 是否以稀疏矩阵形式表示哈密顿量。

返回:

哈密顿量数据列表,每个元组包含表示和复数值。

返回类型:

List[Tuple[Dict[int, str], float]]

to_matrix() numpy.ndarray

返回 Pauli 算符的矩阵表示。

返回:

Pauli 算符的矩阵表示。

返回类型:

numpy.ndarray

to_string() str

返回 Pauli 算符的字符串表示。

返回:

Pauli 算符的字符串表示。

返回类型:

str

我们可以很容易的通过各种方式构造泡利算符类,例如

from pyqpanda import *

if __name__=="__main__":
    # 构造一个空的泡利算符类
    p1 = PauliOperator()

    # 2倍的"泡利Z0"张乘"泡利Z1"
    p2 = PauliOperator("Z0 Z1", 2)

    # 2倍的"泡利Z0"张乘"泡利Z1" + 3倍的"泡利X1"张乘"泡利Y2"
    p3 = PauliOperator({"Z0 Z1": 2, "X1 Y2": 3})

    # 构造一个单位矩阵,其系数为2,等价于p4 = PauliOperator("", 2)
    p4 = PauliOperator(2)

其中PauliOperator p2("Z0 Z1", 2)表示的是 \(2\sigma_{0}^{z}\otimes\sigma_{1}^{z}\)

备注

构造泡利算符类的时候,字符串里面包含的字符只能是空格、 \(X\)、 \(Y\) 和 \(Z\)中的一个或多个,包含其它字符将会抛出异常。 另外,同一个字符串里面同一泡利算符的比特索引不能相同,例如:PauliOperator("Z0 Z0", 2)将会抛出异常。

泡利算符类之间可以做加、减、乘等操作,计算返回结果还是一个泡利算符类。

a = PauliOperator("Z0 Z1", 2)
b = PauliOperator("X5 Y6", 3)

plus = a + b
minus = a - b
muliply = a * b

泡利算符类支持打印功能,我们可以将泡利算符类打印输出到屏幕上,方便查看其值。

a = PauliOperator("Z0 Z1", 2)

print(a)

我们在实际使用的时候,常常需要知道该泡利算符类操作了多少个量子比特,这时候我们通过调用泡利算符类getMaxIndex接口即可得到。 如果是空的泡利算符类调用getMaxIndex接口则返回0,否则返回其最大下标索引值加1的结果。

a = PauliOperator("Z0 Z1", 2)
b = PauliOperator("X5 Y6", 3)

# 输出的值为1
print(a.getMaxIndex())
# 输出的值为6
print(b.getMaxIndex())

如果我们构造的的泡利算符类,其中泡利算符的下标索引不是从0开始分配的,例如PauliOperator("X5 Y6", 3)调用getMaxIndex接口返回的使用的比特数是7,其实 只使用了2个比特。我们如何才能返回其真实用到的比特数呢。我们可以调用泡利算符类里面remapQubitIndex接口,它的功能是对泡利算符类中的索引从0比特开始分配映射, 并返回新的泡利算符类,该接口需要传入一个map来保存前后下标的映射关系。

b = PauliOperator("X5 Y6", 3)

index_map = {}
a = b.remapQubitIndex(index_map)

# 输出的值为 6
print(b.getMaxIndex())
# 输出的值为 1
print(a.getMaxIndex())

实例

以下实例主要是展示 PauliOperator 接口的使用方式。

from pyqpanda import *

if __name__=="__main__":

    a = PauliOperator("Z0 Z1", 2)
    b = PauliOperator("X5 Y6", 3)

    plus = a + b
    minus = a - b
    muliply = a * b

    print("a + b = ", plus)
    print("a - b = ", minus)
    print("a * b = ", muliply)

    print("Index : ", muliply.getMaxIndex())

    index_map = {}
    remap_pauli = muliply.remapQubitIndex(index_map)

    print("remap_pauli : ", remap_pauli)
    print("Index : ", remap_pauli.getMaxIndex())

输出结果如下:

a + b =  {
"Z0 Z1" : 2.000000,
"X5 Y6" : 3.000000
}

a - b =  {
"Z0 Z1" : 2.000000,
"X5 Y6" : -3.000000
}

a * b =  {
"Z0 Z1 X5 Y6" : 6.000000
}

Index :  6
remap_pauli :  {
"Z0 Z1 X2 Y3" : 6.000000
}

Index :  3

费米子算符类

我们用如下的记号标识来表示费米子的两个形态, 湮没: \(X\) 表示 \(a_x\) , 创建: \(X +\) 表示 \(a_x^\dagger\) , 例如: "1 + 3 5 + 1"则代表 \(a_1^\dagger \ a_3 \ a_5^\dagger \ a_1\)

整理规则如下

1. 不同数字

\[''1\quad 2'' = -1 * ''2\quad 1''\]
\[''1 + 2 +'' = -1 * ''2 + 1 +''\]
\[''1 + 2'' = -1 * ''2\quad 1 +''\]

2. 相同数字

\[''1\quad 1 + '' = 1 + ''1 + 1''\]
\[''1 + 1 + '' = 0\]
\[''1\quad 1'' = 0\]

PauliOperator 类似,FermionOperator 类也提供了费米子算符之间加、减和乘的基础的运算操作。通过整理功能可以得到一份有序排列的结果。

class FermionOperator

费米子算符类,用于生成和操作费米子算符集合,主要用于量子化学等领域的模拟和计算。

__init__()

初始化 FermionOperator 类的实例。

__init__(scalar: float)

初始化 FermionOperator 类的实例。

参数:

scalar (float) -- 标量值。

__init__(scalar: complex)

初始化 FermionOperator 类的实例。

参数:

scalar (complex) -- 复数标量值。

__init__(term: str, scalar: complex)

初始化 FermionOperator 类的实例。

参数:
  • term (str) -- 项的标识字符串,表示费米子项。

  • scalar (complex) -- 复数标量值。

__init__(terms: Dict[str, complex])

初始化 FermionOperator 类的实例。

参数:

terms (Dict[str, complex]) -- 复数标量值和项的字典,键为项的标识字符串。

data() List[Tuple[Tuple[List[Tuple[int, bool]], str], complex]]

获取费米子算符数据。

返回:

包含费米子项的列表,每个元组为一项,包含项的信息和复数标量值。

返回类型:

List[Tuple[Tuple[List[Tuple[int, bool]], str], complex]]

error_threshold() float

获取误差阈值。

返回:

误差阈值。

返回类型:

float

isEmpty() bool

判断费米子算符是否为空。

返回:

如果费米子算符为空,则为 True,否则为 False。

返回类型:

bool

normal_ordered() FermionOperator

对费米子算符进行正则排序。

返回:

经过正则排序后的费米子算符。

返回类型:

FermionOperator

setErrorThreshold(threshold: float) None

设置误差阈值。

参数:

threshold (float) -- 误差阈值。

toString() str

获取费米子算符的字符串表示。

返回:

费米子算符的字符串表示。

返回类型:

str

to_string() str

获取费米子算符的字符串表示。

返回:

费米子算符的字符串表示。

返回类型:

str

实例

from pyqpanda import *

if __name__=="__main__":

    a = FermionOperator("0 1+", 2)
    b = FermionOperator("2+ 3", 3)

    plus = a + b
    minus = a - b
    muliply = a * b

    print("a + b = ", plus)
    print("a - b = ", minus)
    print("a * b = ", muliply)

    print("normal_ordered(a + b) = ", plus.normal_ordered())
    print("normal_ordered(a - b) = ", minus.normal_ordered())
    print("normal_ordered(a * b) = ", muliply.normal_ordered())
a + b =  {
0 1+ : 2.000000
2+ 3 : 3.000000
}

a - b =  {
0 1+ : 2.000000
2+ 3  : -3.000000
}

a * b =  {
0 1+ 2+ 3 : 6.000000
}

normal_ordered(a + b) =  {
1+ 0 : -2.000000
2+ 3 : 3.000000
}

normal_ordered(a - b) =  {
1+ 0 : -2.000000
2+ 3  : -3.000000
}

normal_ordered(a * b) =  {
2+ 1+ 3 0 : 6.000000
}

基础逻辑门转换

简介

在NISQ时代,量子计算机无法做到任意逻辑门的运行。因此需要将其转化为量子芯片所支持的基础逻辑门集合以实现通用计算。在本源量子芯片中所支持的单双门组合则为 \(U_3\)\(CZ\) 。 因此,在编译量子程序时,QPanda会对非基础逻辑门进行转换。

原理

首先,定义 \(\phi\)\(XY\) 平面内某一旋转轴与 \(X\) 正向的夹角,则对任意 \(XY\) 旋转门,有:

\[\begin{split}\begin{aligned} R_\phi(\theta) = cos\frac{\theta}{2}I - i sin\frac{\theta}{2}(cos\phi\sigma_x + sin\phi\sigma_y) = \begin{pmatrix} cos\frac{\theta}{2} & -i sin\frac{\theta}{2}e^{-i\phi} \\ -isin\frac{\theta}{2}e^{i\phi} & cos\frac{\theta}{2} \end{pmatrix} \end{aligned}\end{split}\]

Z旋转门的形式如下:

\[\begin{split}\begin{aligned} R_Z(\theta) = cos\frac{\theta}{2}I - i sin\frac{\theta}{2}\sigma_Z = \begin{pmatrix} 1 & 0 \\ 0 & e^{i\theta} \end{pmatrix} \end{aligned}\end{split}\]

易证:

\[\begin{aligned} R_X(\theta_X)R_Z(\theta_Z) = R_Z(\theta_Z)R_{-\theta_Z}(\theta_X) \end{aligned}\]
\[\begin{aligned} R_Z(\theta_{Z2})R_Z(\theta_{Z1}) = R_Z(\theta_{Z1} + \theta_{Z2}) \end{aligned}\]
\[\begin{aligned} CZ[R_Z(\theta_{Z1}) \otimes R_Z(\theta_{Z2})] = [ R_Z(\theta_{Z1} \otimes R_Z(\theta_{Z2}) ]·CZ \end{aligned}\]

以上公式是Virtual Z 门的基础。它意味着,我们可以将线路中已有的Z操作转移到XY操作之后,作为替代,原XY操作的旋转轴将随之变换。而被转移到线路后排的Z操作可以合并,并继续转移,以此类推。

这里我们用单比特的SU(2)门来举例证明:

\[\begin{split}\begin{aligned} U(\theta , \phi ,\lambda) = \begin{bmatrix} cos\frac{\theta}{2} & -isin\frac{\theta}{2}e^{i\lambda} \\ -isin\frac{\theta}{2}e^{i\phi} & cos\frac{\theta}{2}e^{i(\lambda + \phi)} \end{bmatrix} \end{aligned}\end{split}\]

利用

\[\begin{aligned} R_X(\theta) = R_Z(-\frac{\pi}{2})R_X(\frac{\pi}{2})R_Z(\pi - \theta)R_X(\frac{\pi}{2})R_Z(-\frac{\pi}{2}) \end{aligned}\]

最终得到

\[\begin{aligned} U(\theta , \phi ,\lambda) = R_Z(\phi - \frac{\pi}{2})R_X(\frac{\pi}{2})R_Z(\pi - \theta)R_X(\frac{\pi}{2})R_Z(\lambda - \frac{\pi}{2}) = R_Z(\phi + \lambda - \theta)R_{\frac{\pi}{2} + \lambda - \theta}(\frac{\pi}{2})R_{\lambda - \frac{\pi}{2}}(\frac{\pi}{2}) \end{aligned}\]

可见,任意的SU(2)门都可以轻易转化成两个任意旋转轴的 \(\pi/2\) 门,以及一个Vritual Z 门。

代码示例

这里我们对前一节QSD分解之后的线路使用Vritual Z 门进行转换,只需要执行下面这行代码即可。

from pyqpanda import *
import numpy as np
from scipy.stats import unitary_group

if __name__ == "__main__":
    machine = CPUQVM()
    machine.init_qvm()
    q = machine.qAlloc_many(3)
    c = machine.cAlloc_many(3)

    # 生成任意酉矩阵
    unitary_matrix = unitary_group.rvs(2**3,random_state=169384)

    # 输入需要被分解的线路
    prog = QProg()
    prog<<matrix_decompose(q,unitary_matrix,mode=DecompositionMode.QSDecomposition)
    virtual_prog = virtual_z_transform(prog, machine)
    draw_qprog(prog, "pic")
_images/QCircuit_virtualz.jpg

基础逻辑门转换

在量子计算的量子线路设计中,基础逻辑门的标准表示形式是量子门集合的一种形式。这些基础门包括Hadamard门(H门)、Pauli门(X门、Y门、Z门)、CNOT门等。然而,在实际的量子线路设计和优化过程中,经常需要进行基础逻辑门的转换,以便更好地适应特定的硬件或算法需求。

一个常见的转换任务是将带有角度参数的单比特门(例如相位门)转换为通用的单比特门形式,如U3门。U3门是一个通用的单比特量子门,可以表示任意的单比特旋转操作。这样的转换可以提高线路的灵活性,使得线路更容易优化和映射到不同的量子硬件上。

作为基础逻辑门转换的接口,我们提供了一组功能强大的工具,用于将不同形式的基础门相互转换。用户可以使用这些接口来实现自定义的门转换策略,以满足其特定的设计需求。这些接口支持将门转换为等效的门序列,同时保留线路的功能等效性。这样的门转换工具对于量子编译器和量子线路优化的各个阶段都具有重要的作用。

我们使用 transform_to_base_qgate 进行基础门转换,接口定义如下

transform_to_base_qgate

transform_to_base_qgate(qprog: QProg, machine: QuantumMachine, convert_single_gates: List[str], convert_double_gates: List[str]) QProg

Basic quantum gate conversion

Args:

qprog (QProg): Quantum program machine (QuantumMachine): Quantum machine convert_single_gates (List[str]): List of quantum single gates to convert convert_double_gates (List[str]): List of quantum double gates to convert

Returns:

QProg: A new quantum program after the transformation

This function performs basic quantum gate conversion on the given quantum program using the specified quantum machine. It allows the conversion of specific sets of single and double gates, as defined by the lists convert_single_gates and convert_double_gates, respectively.

from pyqpanda import *
from typing import List

qprog = QProg()
machine = QuantumMachine()
convert_single_gates = ["H", "T"]
convert_double_gates = ["CNOT", "CZ"]

# Perform quantum gate conversion
new_qprog = transform_to_base_qgate(qprog, machine, convert_single_gates, convert_double_gates)

# Print the new quantum program
print(new_qprog)

量子比特映射

简介

量子比特映射是指在量子计算中,将抽象的量子逻辑比特(qubit)映射到物理系统中的实际量子比特上的过程。由于量子计算机的构建涉及物理层面的限制和噪声,因此需要将抽象的量子逻辑转化为在实际量子硬件上可以操作的形式。 在量子计算中,一个量子逻辑比特是抽象的计算单元,通常被建模为一个复数的线性组合。然而,实际的量子硬件(比如量子比特在量子芯片上的物理实现)可能受到噪声、耦合等因素的影响,因此需要将量子逻辑比特映射到物理比特上。这个映射通常是一个复杂的过程,涉及硬件架构、噪声特性、量子门的实现等。 其中最为受限的则是纠缠映射,如果计算中需要纠缠操作,那么需要将逻辑上的纠缠映射到物理上的纠缠,同时考虑硬件的限制。

算法原理

Sabre算法

Sabre算法是一种适用于任意比特之间连接的量子拓扑结构,引入衰减效应来优化搜索步骤减少生成线路的深度,最后将逻辑比特映射到物理比特上。接下来介绍该算法在量子线路上的实际应用。 下图展示本源量子计算机中一种量子拓扑结构,我们用双向箭头来表示两个直接相邻的量子比特。

_images/BY.PNG

由于在物理层面上存在量子比特排布的限制,只能允许两个相邻的量子比特之间进行计算。例如在这个图中,\(Q_0\)\(Q_1\)\(Q_7\) 通过耦合器直接相连,我们可以在 \(\{ Q_0,Q_5\}\) , \(\{ Q_0,Q_7\}\) 这两组量子比特之间插入CNOT门。 但是如果我们想要在 \(\{ Q_0,Q_6\}\) 之间插入CNOT门的话,是无法直接实现的,因为 \(Q_0\)\(Q_6\) 不直接相连。也就是说,我们无法直接在两个不相连的量子比特之间插入一个CNOT门。

接下来,我们使用下图中一个简单4比特的量子线路来说明量子比特映射中的问题。在这个结构中,被允许直接进行计算的量子对有:\(\{ Q_0,Q_1\}\), \(\{ Q_1,Q_2\}\), \(\{ Q_2,Q_3\}\), \(\{ Q_3,Q_0\}\) ,不能直接进行计算的有:\(\{ Q_0,Q_2\}\) , \(\{ Q_1,Q_3\}\) 。对于给出的含有三个CNOT门的量子线路中,我们假定初始逻辑比特和物理比特的映射关系是 \(\{ q_0 \mapsto Q_0, q_1 \mapsto Q_1, q_2 \mapsto Q_2, q_3 \mapsto Q_3,\}\)

_images/4topo.PNG

在图中,我们发现门 \(G_2\) 连接的两个量子比特是 \(Q_0\)\(Q_2\) ,但是这样的CNOT门在实际的计算机中无法实现,因此我们通过使用SWAP门, 来移动 \(Q_0\) 或者 \(Q_2\) 的位置,使它们相邻并可以计算。通过在下图中,插入两个SWAP门,就可以使线路中所有的SWAP门可以进行计算。

_images/swap_exa.PNG

Sabre算法就是通过寻找可以插入SWAP门的位置,来对线路进行优化,使得原本不可以在量子计算机上运行的量子门,通过动态的改变量子比特的邻接位来使得所有的量子门都能够进行计算。 以前的工作通常采用基于映射的穷举式搜索来寻找有效的映射转换。Sabre通过设计一个启发式成本函数,通过限制生成线路的深度,来帮助找到插入SWAP门的位置。

pyqpanda中基于sabre映射算法的接口是 sabre_mapping

sabre_mapping(prog: QProg, quantum_machine: QuantumMachine, init_map: List[int], max_look_ahead: int = 20, max_iterations: int = 10, config_data: str = 'QPandaConfig.json') QProg

该函数执行 Sabre 映射算法,用于对给定量子程序进行映射以优化其执行,支持多种重载形式。

参数:
  • prog (QProg) -- 目标量子程序。

  • quantum_machine (QuantumMachine) -- 量子计算机。

  • init_map (List[int]) -- 初始映射列表。

  • max_look_ahead (int, optional) -- Sabre 映射的最大前瞻步数。默认为 20。

  • max_iterations (int, optional) -- Sabre 映射的最大迭代次数。默认为 10。

  • config_data (str, optional) -- 配置数据,用于加载配置。默认为 'QPandaConfig.json'。

  • arch_matrix (numpy.ndarray[numpy.float64[m,n]], optional) -- 拓扑结构矩阵,用于特定重载。

返回:

映射优化后的量子程序。

返回类型:

QProg

示例用法:

# 使用初始映射和默认参数进行 Sabre 映射
mapped_prog = sabre_mapping(my_prog, my_quantum_machine, init_map=[0, 1, 2])

# 使用自定义拓扑结构矩阵进行 Sabre 映射
custom_arch_matrix = numpy.array(...)  # 自定义拓扑结构矩阵
mapped_prog = sabre_mapping(my_prog, my_quantum_machine, init_map=[0, 1, 2], arch_matrix=custom_arch_matrix)

我们以一维链的邻接矩阵为例,首先构建一维链的邻接矩阵并输出

import numpy as np
import matplotlib.pyplot as plt

# 创建一个6个节点的邻接矩阵
num_nodes = 6
chain_graph = np.zeros((num_nodes, num_nodes), dtype=np.double)

for i in range(num_nodes - 1):
    chain_graph[i, i + 1] = 1
    chain_graph[i + 1, i] = 1

# 绘制邻接矩阵
plt.imshow(chain_graph, cmap='viridis', interpolation='nearest')
plt.title("Adjacency Matrix of a 1D Chain")
plt.xlabel("Nodes")
plt.ylabel("Nodes")
plt.colorbar(label="Connection")
plt.show()

可以看到一维链的结构如下图

_images/arch.png

我们需要对如下量子程序进行映射

_images/mapping.jpg

示例代码为

from pyqpanda import *
import numpy as np

if __name__ == "__main__":

    machine = CPUQVM()
    machine.init_qvm()

    q = machine.qAlloc_many(6)

    prog = QProg()
    prog << CNOT(q[0],q[5])<< CNOT(q[4],q[1])<< CNOT(q[3],q[0])<< CNOT(q[2],q[5])

    num_nodes = 6
    chain_graph = np.zeros((num_nodes, num_nodes), dtype=np.double)

    for i in range(num_nodes - 1):
        chain_graph[i, i + 1] = 1
        chain_graph[i + 1, i] = 1

    sabre_result = sabre_mapping(prog, machine, 20, 10, chain_graph)
    draw_qprog(sabre_result,'pic')

由于sabre算法具备随机性,因此映射结果并不固定,此次结果为:

_images/sabre_mapping.jpg

BMT算法

除了Sabre算法,BMT拓扑映射算法通过将量子程序转换称DAG(有向无环图)数据结构,通过对线路重构来生成新的量子程序。因为每次插入一个SWAP门,都相当于插入了3个CNOT门,SWAP门过多会影响线路的保真度,因此这种做法能够减少SWAP门的使用。

用一个简单的线路举例,对于一个含有3个CNOT门的线路中, \(CNOT_{0,1}\) , \(CNOT_{1,2}\) , \(CNOT_{0,2}\) ,我们可以构建如下图所示的DAG:

_images/DAG.png

然后遍历DAG获取最大子图序列,循环处理执行入度为0的节点(入度为0即为该节点中逻辑门所需的比特处于空闲情况,可以执行当前节点中逻辑门),执行的节点用于构建最大子图,执行完则需要将该节点从DAG去除。处理下一个入度为0的节点。直至DAG中无节点为止。

遍历由量子程序构建的DAG,最终获得以下格式数据,多个最大子图数据和每个对应的同构子图数据和映射关系:

_images/isomorphic.png

结合Token-Swapping技术,寻找最短消耗的映射方法。固定路径:这里主要考虑拓扑结构的最短距离,这里通过BFS算法确定拓扑结构两点间的固定成本。 最大子图都有着自己的映射方法,相邻的最大子图就需要各自映射方法并结合SWAP达到效果。我们就是要将每个最大子图间的SWAP最小化,同时由于每个最大子图有着多种同构情况,所以这里便是一个排列组合问题。我们要做的就是将消耗成本最低的组合情况选择出来。最后生成新的量子程序。

pyqpanda中基于bmt映射算法的接口是 OBMT_mapping

OBMT_mapping(prog: QProg, quantum_machine: QuantumMachine, b_optimization: bool = False, max_partial: int = 4294967295, max_children: int = 4294967295, config_data: str = 'QPandaConfig.json') QProg

该函数用于进行BMT映射,将目标量子程序映射到指定的拓扑结构上,以获得一个映射后的量子程序。可以选择是否开启优化,并可以配置一些映射相关的参数。返回映射后的量子程序。

参数:
  • prog (QProg) -- 目标量子程序。

  • quantum_machine (QuantumMachine) -- 量子计算机。

  • b_optimization (bool, optional) -- 是否开启优化。默认为 False。

  • max_partial (int, optional) -- 每一步的最大部分解数量限制,默认为 4294967295(无限制)。

  • max_children (int, optional) -- 每个双量子门的最大候选解数量限制,默认为 4294967295(无限制)。

  • config_data (str, optional) -- 配置数据文件路径

返回:

映射后的量子程序。

返回类型:

QProg

OBMT_mapping(prog: QProg, quantum_machine: QuantumMachine, b_optimization: bool, arch_matrix: numpy.ndarray[numpy.float64[m, n]]) QProg

该函数用于进行BMT映射,将目标量子程序映射到指定的拓扑结构上,以获得一个映射后的量子程序。可以选择是否开启优化,并可以配置一些映射相关的参数。返回映射后的量子程序。

参数:
  • prog (QProg) -- 目标量子程序。

  • quantum_machine (QuantumMachine) -- 量子计算机。

  • b_optimization (bool) -- 是否开启优化。

  • arch_matrix (numpy.ndarray[numpy.float64[m,n]]) -- 架构图矩阵。

返回:

映射后的量子程序。

返回类型:

QProg

示例用法:

# 使用初始映射和默认参数进行BMT映射
mapped_prog_default = OBMT_mapping(my_prog, my_quantum_machine, b_optimization=True)

# 使用自定义参数进行BMT映射
custom_max_partial = 100  # 自定义每步最大部分解数量
custom_max_children = 50   # 自定义每个双量子门的最大候选解数量
custom_config_data = 'my_config.json'  # 自定义配置数据文件路径
mapped_prog_custom = OBMT_mapping(my_prog, my_quantum_machine, b_optimization=True, max_partial=custom_max_partial, max_children=custom_max_children, config_data=custom_config_data)

# 使用初始映射和自定义拓扑结构矩阵进行BMT映射
custom_arch_matrix = numpy.array(...)  # 自定义拓扑结构矩阵
mapped_prog_custom_arch = OBMT_mapping(my_prog, my_quantum_machine, b_optimization=True, arch_matrix=custom_arch_matrix)

我们同样以上述的一维链和输入参数为例:

from pyqpanda import *
import numpy as np

if __name__ == "__main__":

    machine = CPUQVM()
    machine.init_qvm()

    q = machine.qAlloc_many(6)

    prog = QProg()
    prog << CNOT(q[0],q[5])<< CNOT(q[4],q[1])<< CNOT(q[3],q[0])<< CNOT(q[2],q[5])

    num_nodes = 6
    chain_graph = np.zeros((num_nodes, num_nodes), dtype=np.double)

    for i in range(num_nodes - 1):
        chain_graph[i, i + 1] = 1
        chain_graph[i + 1, i] = 1

    obmt_mapping_result = OBMT_mapping(prog,machine,True,chain_graph)

映射后的结果为:

_images/obmt_mapping.jpg

量子逻辑门分解

简介

量子逻辑门分解是指将一个复杂的量子逻辑门拆解成一系列基本的量子逻辑门的组合。在量子计算中,量子逻辑门是用于对量子比特进行操作和计算的基本单元。通过将复杂的逻辑门分解成基本的逻辑门,可以更容易地实现复杂的量子计算任务。量子逻辑门分解通常遵循一些特定的量子门集合,例如单量子比特门(如Hadamard门、相位门、旋转门等)和双量子比特门(如CNOT门、SWAP门等)。通过使用这些基本门,可以将任意的量子逻辑门拆解成一系列的基本门序列。 这个分解的过程类似于在经典计算中,将复杂的逻辑函数分解成基本的逻辑门(例如AND、OR、NOT等)的组合。量子逻辑门分解在量子算法设计、误差校正和量子编程中起着重要作用,因为它允许我们将复杂的问题分解成更易于实现和控制的部分。

CS 分解

Cosine-Sine Decomposition,我们称为CS分解,或者CSD。首先我们回顾以下在矩阵计算中的CS(Cosine-Sine)分解,在CS分解中,对于一个偶数维度的酉矩阵 \(U \in \mathbb{C}^{l\times l}\) 能被分解成更小的矩阵 \(A_1, A_2, B_1, B_2\) 和实数对角矩阵 \(C, S\) , 其中 \(C^2 + S^2 = I_{l/2}\)

\[\begin{split}\begin{aligned} U = \begin{pmatrix} A_1 & \\ & B_1 \end{pmatrix}\begin{pmatrix} C & -S \\ S & C \end{pmatrix}\begin{pmatrix} A_2 & \\ & B_2 \end{pmatrix} \end{aligned}\end{split}\]

对于一个矩阵U,左右两部分 \(A_j \oplus B_j\) 是由最重要的量子比特控制的量子多路器,它决定了 \(A_j, B_j\) 是否被应用到低位的比特上。中间部分与 \(R_y\) 门的结构相同, 仔细观察可以发现 对于低位比特的每一个经典配置,将 \(R_y\) 门应用在最有效位上。因此CS分解可以写成以下形式:

_images/CS_1.png

对于多路CS分解,我们可以通过MEP(多路拓展特性)来增加更多的量子比特。 如下图所示。

_images/CS_2.png

代码示例

from pyqpanda import *
from scipy.stats import unitary_group

if __name__ == "__main__":
    machine = CPUQVM()
    machine.init_qvm()
    q = machine.qAlloc_many(3)
    c = machine.cAlloc_many(3)

    # 生成任意酉矩阵
    unitary_matrix = unitary_group.rvs(2**3,random_state=169384)

    # 输入需要被分解的线路
    prog = QProg()
    prog<<matrix_decompose(q,unitary_matrix,mode=DecompositionMode.CSDecomposition)
    draw_qprog(prog, "pic")
_images/QCircuit_csd.jpg

QS 分解

QS(Quantum Shannon)分解中涉及到多路分解,对于一个多路分解,我们有:

_images/QS_1.png

\(U = U_0 \oplus U_1\) 为可选多路器,我们根据U的实现来设立并解决这个方程,让酉矩阵 \(V,W\) 和酉对角矩阵 \(D\) 满足 \(U = (I \otimes V)(D \oplus D^\dagger)(I \otimes W)\) ,或者写成:

_images/QS_3.png

\(U_1,U_2\) 相乘,消去含 \(W\) 的相关项,得到 \(U_1U_2^\dagger = VD^2V^\dagger\) 。我们能通过这个方程利用对角化从 \(U_1U_2^\dagger\) 中得到 \(D\)\(V\) 。此外 \(W = DV^\dagger U_2\) 。 标记 \(D\) 的对角线,矩阵 \(D \oplus D^\dagger\) 在线路中对应 \(R_z\) 门。

利用新的分解,我们在CS分解中的两边的多路器在进行分解,就能得到递归应用的通用算符分解:

_images/QS_2.png

因此,一个任意的n量子比特操作算子可以由三个复合R门和四个通用 \(n - 1\) 比特的操作算子来实现,这些算子可以被看作是原始算子的辅助因子。

代码示例

from pyqpanda import *
from scipy.stats import unitary_group

if __name__ == "__main__":
    machine = CPUQVM()
    machine.init_qvm()
    q = machine.qAlloc_many(3)
    c = machine.cAlloc_many(3)

    # 生成任意酉矩阵
    unitary_matrix = unitary_group.rvs(2**3,random_state=169384)

    # 输入需要被分解的线路
    prog = QProg()
    prog<<matrix_decompose(q,unitary_matrix,mode=DecompositionMode.QSDecomposition)
    draw_qprog(prog, "pic")
_images/QCircuit_qsd.jpg

多控门分解

目前,由于量子计算的发展受到芯片的运行逻辑门集的限制,无法执行多比特量子逻辑门,因此针对多比特门,需要进行量子线路的重新表征。

而在多比特门中最为常用的则是多比特控制门,例如Grover算法中所需的数据索引空间表示,HHL算法中的uncompute模块的构建等

同时,为了使量子程序保真度达到所需阈值之上,降低线路深度则是一种有效的方法。

通常我们使用量子虚拟机来模拟多控门量子线路,对于某些量子虚拟机而言,含有多控门的量子线路通常线路深度较深,无法满足模拟要求,下图是一种常用的多控门分解方案,其中 \(V^4=U\)

_images/multi_control.png

不同的分解算法效果天差地别,量子线路的有效分解可以降低量子计算的时间和噪声产生的影响。而由于有噪声的影响,量子线路的大小就受到了限制;那么最小化量子线路的深度在实现量子算法起到 至关重要的作用。

分解方案的核心目的是提高量子线路分解的有效性,分解有效性的衡量标准有:
    1. 分解后量子线路的深度

    1. 分解的单量子逻辑门和双量子逻辑门的数量

    1. 是否需要辅助量子比特等

在更加复杂的量子算法场景下,将会出现更多的、受控维度更高的多控门。目前实现的物理量子计算机基本都不支持多控门,并且我们无法保证所有的受控物理qubit都处于连通状态(目前的物理量子芯片都有固定的拓扑结构),所以想要在真实物理量子计算机上运行量子算法,首先要对多控门进行拆解,使其转换成N个量子芯片支持的逻辑门的组合,以适配目标量子芯片。

方案细节

这里我们是用一种基于线性深度的多控门分解方案,其基本思想是,将控制位的数量逐次分解递减,多控门逐步分解为受控比特递减的多控门组合,然后这些多控门再一次递归分解,直到控制比特为1,

其中线性深度的含义是针对量子线路深度随量子比特线性增长的分解方案,而不是分解复杂度线性增加,得到的最终产物是多个单比特控制位单门集合,具体步骤如下:

  • 1. 对于任意符合n个控制比特的多控门,均可用如下形式表示

    \[\large C^{n}U=Q_{n}^{\dagger}P_n(U)^{\dagger}Q_{n}(a_1\sqrt[2^{n-1}]{U}a_{n+1})P_n(U)\]

    其中 \(a_jU_{a_k}\) 表示一个由单量子位控制的单门,控制比特是 \({a_j}\) ,目标比特是 \(a_k\) ,同时 \(C^{n}U\) 表示多量子位控制,控制比特是 \({a_1,···,a_n}\) ,目标比特是 \({a_{n+1}}\)

  • 2. 第一次分解会得到四个子式,相当于四个子量子线路或量子逻辑门,其中:

    \(\large Q_n=\prod_{k=1}^{n-1}C^kR_x(\pi)\)

    \(\large P_n(U)=\prod_{k=2}^na_k\sqrt[2^{n-k+1}]{U}a_{n+1}\)

    在上述式子中, \(\large P_n(U)\) 是多个单控制位量子逻辑门组合, \(\large Q_n\) 是控制位数量-1的多控门组合,具体地可以推导出,即每次分解后依然存在多控门,但是多控门的控制位数量递减,即

    \[\large Q_n=Q_{n-1}C^{n-1}R_x(\pi)\]
  • 3. 继续重复上述过程,知道控制比特为1

上述方案适用于所有单门受控比特情形,双量子逻辑门的控制场景下,可以先做进一步转化,转化为一个或多个多控制位的的单量子逻辑门集合,对于CNOT、CZ、CR、CU等,可以依次看作X、Z、U1、U4的单门控制形式,对于交换门,如SWAP,ISWAP和SQISWAP等,可以转化为上述支持的基础单双门组合。

多控门分解接口

ldd_decompose(qprog: QProg) QProg

该函数用于分解多控制量子门,以得到一个新的量子程序,其中多控制量子门被分解成更基本的单比特和双比特门的序列。

参数:

qprog (QProg) -- 要进行分解的量子程序。

返回:

经过分解后的新量子程序。

返回类型:

QProg

我们以上图的四比特控制门为例,

from pyqpanda import *
import numpy as np

if __name__ == "__main__":
    machine = CPUQVM()
    machine.init_qvm()
    q = machine.qAlloc_many(4)
    c = machine.cAlloc_many(4)

    # 输入需要被分解的线路
    prog = QProg()
    prog << X(q[3]).control([q[0],q[1],q[2]])

    #执行多控门分解操作
    after_prog = ldd_decompose(prog)
    draw_qprog(after_prog, "pic")

可以得到分解的结果为:

_images/multi_result.jpg

OriginIR

OriginIR是基于QPanda的量子程序中间表示,对QPanda各种特性的支持有非常重要的作用。OriginIR不仅可以表示绝大部分量子逻辑门类型,表示针对量子线路的dagger操作,为量子线路添加控制比特,还可以支持QPanda独有的Qif、QWhile,可以实现量子程序内嵌经典程序。

OriginIR主要内容有量子比特、经典寄存器、量子逻辑门、转置共轭操作、添加控制比特操作、QIf、QWhile、经典表达式。

量子比特

OriginIR使用QINIT申请量子比特,其格式为QINIT后跟空格+量子比特总数。示例:QINIT 6。需要注意的是除注释外QINIT必须出现在OriginIR程序的第一行。 在使用量子比特时,OriginIR使用q[i]表示某个具体的量子比特,此处i为量子比特的编号,i可为无符号数字型常量,也可为变量,同时也可使用c[i]组成的表达式代替,示例:q[1],q[c[0]],q[c[1]+c[2]+c[3]]。

经典寄存器

OriginIR使用CREG申请经典寄存器,其格式为CREG后跟空格+经典寄存器总数。示例:CREG 6; 在使用经典寄存器时,OriginIR使用c[i]表示某个具体的经典寄存器,i为经典寄存器编号,此处i必须为无符号数字型常量;示例:c[1]。

量子逻辑门

OriginIR把量子逻辑门分为以下几个种类:单门无参数型关键字;单门一个参数型;单门两个参数;单门三个参数;单门四个参数;双门无参数;双门一个参数;双门四个参数;三门无参数。 需要注意的是所有单门操作,目标量子比特可以是整个量子比特数组或者单个量子比特。如果是整个量子比特数组时例如:

H q

当量子比特数组大小为3时则等效为:

H q[0]
H q[1]
H q[2]

1、单门无参数型关键字:H、T、S、X、Y、Z、X1、Y1、Z1、I;表示无参数类型的单量子逻辑门;格式为量子逻辑门关键字+空格+目标量子比特。示例:

H q[0]

2、单门一个参数型关键字:RX、RY、RZ、U1;表示有一个参数的单量子逻辑门;格式为量子逻辑门关键字+空格+目标量子比特+逗号+(偏转角度)。示例:

RX q[0],(1.570796)

3、 单门两个参数型关键字:U2、RPhi;表示有两个参数的单量子逻辑门;格式为量子逻辑门关键字+空格+目标量子比特+逗号+(两个偏转角度)。示例:

U2 q[0],(1.570796,-3.141593)

4、 单门三个参数型关键字:U3;表示有三个参数的单量子逻辑门;格式为量子逻辑门关键字+空格+目标量子比特+逗号+(三个偏转角度)。示例:

U3 q[0],(1.570796,4.712389,1.570796)

5、单门四个参数关键字:U4;表示有四个参数的单量子逻辑门;格式为量子逻辑门关键字+空格+目标量子比特+逗号+(四个偏转角度)。示例:

U4 q[1],(3.141593,4.712389,1.570796,-3.141593)

6、双门无参数型关键字:CNOT、CZ、ISWAP、SQISWAP、SWAP;表示无参数的双量子逻辑门;格式为量子逻辑门关键字+空格+控制比特+逗号+目标比特。示例:

CNOT q[0],q[1]

7、双门一个参数型关键字:ISWAPTHETA、CR;表示有一个参数的双量子逻辑门;格式为量子逻辑门关键字+空格+控制比特+逗号+目标比特+逗号+(偏转角度)。示例:

CR q[0],q[1],(1.570796)

8、双门四个参数型关键字:CU;表示有四个参数的双量子逻辑门;格式为量子逻辑门关键字+空格+控制比特+逗号+目标比特+逗号+(四个偏转角度)。示例:

CU q[1],q[3],(3.141593,4.712389,1.570796,-3.141593)

9、 三门无参数型关键字:TOFFOLI;表示无参数的三量子逻辑门;格式为量子逻辑门关键字+空格+控制比特1+逗号+控制比特2+逗号+目标比特。示例:

TOFFOLI  q[0],q[1],q[2]

转置共轭操作

OriginIR中可以对一个或多个量子逻辑门进行转置共轭操作,OriginIR使用DAGGER和 ENDDAGGER关键字定义转置共轭操作的范围,一个DAGGER必须有一个ENDDAGGER匹配,示例:

DAGGER
H q[0]
CNOT q[0],q[1]
ENDDAGGER

添加控制比特操作

OriginIR中可以对一个或多个量子逻辑门添加控制比特,OriginIR使用CONTROL 和 ENDCONTROL关键字定义添加控制比特的范围,CONTROL后跟空格+控制比特列表;示例:

CONTROL q[2],q[3]
H q[0]
CNOT q[0],q[1]
ENDCONTROL

QIF

OriginIR中可以表示量子条件判断程序,它通过QIF、ELSE、ENDIF框定量子条件判断程序的不同分支的范围。QIF必须匹配一个ENDIF,如果QIF有两个分支则需要有ELSE,如果QIF只有一个分支则不需要有ELSE;QIF后跟空格+判断表达式。示例:

1、QIF只有一个条件分支
QIF c[0]==c[1]
H q[0]
CNOT q[0],q[1]
ENDQIF

2、QIF有两个条件分支
QIF c[0]+c[1]<5
H q[0]
CNOT q[0],q[1]
ELSE
H q[0]
X q[1]
ENDQIF

QWHILE

OriginIR中可以表示量子循环判断程序,它通过QWHILE和ENDQWHILE框定循环判断程序的范围,QWHILE必须匹配一个ENDQWHILE;QWHILE后跟空格+判断表达式。示例:

QWHILE c[0]<5
H q[c[0]]
c[0]=c[0]+1
ENDQWHILE

经典表达式

OriginIR可以在量子程序中嵌入经典表达式,如c[0]==c[1]+c[2];使用示例:

QWHILE c[0]<5
H q[c[0]]
c[0]=c[0]+1
ENDQWHILE

该示例表示对q[0]~q[4]比特做H门操作;经典表达式中必须是经典寄存器和常量组成的表达式;经典表达式的操作符有

{PLUS , "+"},
{MINUS, "-"},
{MUL, "*"},
{DIV, "/"},
{EQUAL, "==" },
{ NE, "!=" },
{ GT, ">" },
{ EGT, ">=" },
{ LT, "<" },
{ ELT, "<=" },
{AND, "&&"},
{OR, "||"},
{NOT, "!"},
{ASSIGN, "=" }

MEASURE操作

MEASURE表示对指定的量子比特进行测量操作,并把结果保存到指定的经典寄存器中。MEASURE后跟空格+目标量子比特+‘,’+目标经典寄存器。示例:

MEASURE q[0],c[0]

如果申请的量子比特和经典寄存器数量相同。可以使用q表示所有量子比特,c表示所有经典比特。示例:

MEASURE q,c

如果量子比特和经典比特数量都为3,则等效为

MEASURE q[0],c[0]
MEASURE q[1],c[1]
MEASURE q[2],c[2]

RESET操作

RESET操作是将操作的量子比特的量子态恢复到0态。格式为RESET+空格+目标量子比特。其中目标量子比特可以是整个量子比特数组或者单个量子比特。 示例:

RESET q

RESET q[1]

BARRIER操作

BARRIER操作是将操作的量子比特进行阻断,防止在线路优化和执行过程。 格式为BARRIER+空格+目标量子比特。其中目标量子比特可以是整个量子比特数组或者单个、多个量子比特。示例:

BARRIER q
BARRIER q[0]
BARRIER q[0],q[1],q[2]

QGATE操作

QGATE为自定义逻辑门操作,可以将多个逻辑门组合成一个新的逻辑门使用。 它通过QGATE和ENDQGATE框定自定义逻辑门的范围。同时需要注意的是,自定义逻辑门的形参名不能与上述相关关键字冲突。示例:

QGATE new_H a
H a
X a
ENDQGATE
new_H q[1]
QGATE new_RX a,(b)
RX a,(PI/2+b)
X a
ENDQGATE
new_RX q[1],(PI/4)

OriginIR程序示例

QPE算法

QINIT 3
CREG 2
H q[2]
H q[0]
H q[1]
CONTROL q[1]
RX q[2],(-3.141593)
ENDCONTROL
CONTROL q[0]
RX q[2],(-3.141593)
RX q[2],(-3.141593)
ENDCONTROL
DAGGER
H q[1]
CR q[0],q[1],(1.570796)
H q[0]
ENDDAGGER
MEASURE q[0],c[0]
MEASURE q[1],c[1]

QPanda2提供了OriginIR转换工具接口 convert_qprog_to_originir 该接口使用非常简单。

convert_qprog_to_originir(qprog: QProg, machine: QuantumMachine) str

该函数用于将给定的量子程序转化为 OriginIR 格式的字符串,以便于进一步分析和处理。OriginIR 是一个中间表示(IR),用于表示量子程序的信息。

参数:
  • qprog (QProg) -- 要转化的量子程序。

  • machine (QuantumMachine) -- 用于转化的量子机器。

返回:

转化后的 OriginIR 格式的字符串。

返回类型:

str

该函数接受一个量子程序和一个量子机器作为参数,然后将给定的量子程序转化为 OriginIR 格式的字符串。

示例用法:

# 创建一个量子机器和一个量子程序
machine = CPUQVM()
qvm.init_qvm()

qprog = QProg()

# 将量子程序转化为 OriginIR 格式的字符串
originir_str = convert_qprog_to_originir(qprog, machine)

# 打印转化后的 OriginIR 字符串
print(originir_str)

下面的例程通过简单的接口调用演示了量子程序转化OriginIR的过程

from pyqpanda import *

if __name__ == "__main__":

    machine = CPUQVM()
    machine.init_qvm()
    qlist = machine.qAlloc_many(4)
    clist = machine.cAlloc_many(4)
    prog = QProg()
    prog_cir = QCircuit()

    # 构建量子线路
    prog_cir << Y(qlist[2]) << H(qlist[2]) << CNOT(qlist[0],qlist[1])


    # 构建量子程序
    prog << H(qlist[2]) << Measure(qlist[1],clist[1])

    # 量子程序转换QriginIR,并打印OriginIR
    print(convert_qprog_to_originir(prog,machine))

具体步骤如下:

  • 首先在主程序中用 init_quantum_machine 初始化一个量子虚拟机对象,用于管理后续一系列行为

  • 接着用 qAlloc_manycAlloc_many 初始化量子比特与经典寄存器数目

  • 然后调用 create_empty_qprog 构建量子程序

  • 最后调用接口 convert_qprog_to_originir 输出OriginIR字符串,并用 destroy_quantum_machine 释放系统资源

运行结果如下:

QINIT 4
CREG 4
H q[2]
MEASURE q[1],c[1]

备注

对于暂不支持的操作类型,OriginIR会显示UnSupported XXXNode,其中XXX为具体的节点类型。

通过该功能模块,你可以解析OriginIR文本文件,将其中的量子逻辑门操作信息提取出来,得到QPanda 2内部可操作的量子程序。

QPanda 2提供了OriginIR文件转换工具接口 convert_originir_to_qprog 该接口使用非常简单

convert_originir_to_qprog(file_path: str, machine: QuantumMachine) list

将 OriginIR 指令集转换为量子程序的函数

该函数将 OriginIR 指令集文件转换为量子程序。

param file_path:

OriginIR 文件的文件路径。

type file_path:

str

param machine:

初始化的量子机器。

type machine:

QuantumMachine

return:

包含转换后的 QProg、量子比特列表和经典比特列表的列表。

rtype:

list

raises run_fail:

转换 OriginIR 到 QProg 失败。

该函数的主要目的是读取给定的 OriginIR 指令集文件,并将其转换为一个 QProg 量子程序。要进行转换的 OriginIR 文件路径需要提供,同时需要提供一个初始化的量子机器。返回的结果列表包含了转换后的 QProg,以及用于 QProg 的量子比特列表和经典比特列表。

示例用法:

# 初始化量子机器
qvm = CPUQVM()
qvm.init_qvm()

# 转换 OriginIR 文件为 QProg

result = convert_originir_to_qprog("path/to/originir/file.ir", qvm)
qprog, qubit_list, cbit_list = result

接下来通过简单的接口调用演示了OriginIR转化量子程序的过程

from pyqpanda import *
if __name__=="__main__":

    machine = CPUQVM()
    machine.init_qvm()
    # 编写OriginIR文件
    f = open('testfile.txt', mode='w',encoding='utf-8')
    f.write("""QINIT 4
        CREG 4
        DAGGER
        X q[1]
        X q[2]
        CONTROL q[1], q[2]
        RY q[0], (1.047198)
        ENDCONTROL
        ENDDAGGER
        MEASURE q[0], c[0]
        QIF c[0]
        H q[1]
        H q[2]
        RZ q[2], (2.356194)
        CU q[2], q[3], (3.141593, 4.712389, 1.570796, -1.570796)
        CNOT q[2], q[1]
        ENDQIF""")

    f.close()

    # OriginIR转换量子程序, 返回转换后的量子程序、量子程序使用的量子比特以及经典寄存器
    prog, qv, cv = convert_originir_to_qprog("testfile.txt", machine)

    # 量子程序转换OriginIR,打印并对比转换结果
    print(convert_qprog_to_originir(prog,machine))

具体步骤如下:

  • 首先编写OriginIR,并将其保存到指定文件中

  • 接着在主程序中用 init_quantum_machine 初始化一个量子虚拟机对象,用于管理后续一系列行为

  • 然后调用 convert_originir_to_qprog 接口将OriginIR转换为量子程序

  • 最后调用 convert_qprog_to_originir 接口,把量子程序转为OriginIR,通过比较输入和生成的OriginIR是否相同,判断OriginIR是否正确转换成量子程序,并且用 destroy_quantum_machine 释放系统资源

运行结果如下:

QINIT 4
CREG 4
DAGGER
X q[1]
X q[2]
CONTROL q[1],q[2]
RY q[0],(1.047198)
ENDCONTROL
ENDDAGGER
MEASURE q[0],c[0]
QIF c[0]
H q[1]
ELSE
H q[2]
RZ q[2],(2.356194)
CU q[2],q[3],(3.141593,4.712389,1.570796,-1.570796)
CNOT q[2],q[1]
ENDQIF

备注

对于暂不支持的操作类型,可能会在OriginIR转化成量子程序的过程中发生错误。

QASM


通过该功能模块,你可以解析QASM文本文件,将其中的量子逻辑门操作信息提取出来,得到QPanda 2内部可操作的量子程序。

QASM介绍

QPanda 2提供了QASM文件转换工具接口 convert_qasm_to_qprog 该接口使用非常简单。

convert_qasm_to_qprog(file_path: str, machine: QuantumMachine) list

该函数的作用是从给定的 QASM 文件中读取指令集并将其转换为量子程序,同时需要提供一个已初始化的量子机器实例。

参数:
  • file_path (str) -- QASM 文件路径。

  • machine (QuantumMachine) -- 已初始化的量子机器实例。

返回:

包含转换后的 QProg、量子比特列表和经典比特列表的列表。

返回类型:

list

抛出:

run_fail -- QASM 转换为 QProg 失败。

返回的列表包含了转换后的 QProg 以及与之关联的量子比特列表和经典比特列表。您可以根据需要进一步操作这些信息,例如执行量子程序、获取测量结果等。

示例用法:

# 初始化 QuantumMachine 实例
machine = CPUQVM()
machine.init_qvm()

# 将 QASM 文件转换为 QProg
result = convert_qasm_to_qprog("my_circuit.qasm", machine)
qprog, qubit_list, cbit_list = result

# 执行量子程序并获取测量结果
machine.run(qprog, qubit_list)
measurement_results = machine.get_prob_dict(qubit_list)

接下来通过简单的接口调用演示了QASM转化量子程序的过程

from pyqpanda import *

if __name__=="__main__":

    machine = CPUQVM()
    machine.init_qvm()

    # 编写QASM文件
    f = open('testfile.txt', mode='w',encoding='utf-8')
    f.write("""// test QASM file
        OPENQASM 2.0;
        include "qelib1.inc";
        qreg q[3];
        creg c[3];
        x q[0];
        x q[1];
        z q[2];
        h q[0];
        tdg q[1];
        measure q[0] -> c[0];
        """)
    f.close()

    # QASM转换量子程序, 并返回量子程序、量子比特以及经典寄存器
    prog_trans, qv, cv = convert_qasm_to_qprog("testfile.txt", machine)

    # 量子程序转换QASM
    qasm = convert_qprog_to_qasm(prog_trans,machine)

    # 打印并对比转换结果
    print(qasm)

具体步骤如下:

  • 首先编写QASM,并将其保存到指定文件中。

  • 接着在主程序中用 init_quantum_machine 初始化一个量子虚拟机对象,用于管理后续一系列行为。

  • 然后调用 convert_qasm_to_qprog 接口将QASM转换为量子程序。

  • 最后调用 convert_qprog_to_qasm 接口,把量子程序转为QASM,通过比较量子程序执行结果,判断QASM是否正确转换成量子程序,并且用 destroy_quantum_machine 释放系统资源。

运行结果如下:

OPENQASM 2.0;
include "qelib1.inc";
qreg q[3];
creg c[3];
u3(1.5707963267949037,3.1415926535897931,3.1415926535897931) q[0];
u3(3.1415926535897931,2.3561944901923386,0) q[1];
u3(0,3.1415926535897931,0) q[2];
measure q[0] -> c[0];

备注

上述示例中,由于QASM支持U3门,所以在QProg转QASM时,对量子线路做了优化,输出的QASM中只有U3门,这样可以有效降低量子线路深度。对于暂不支持的操作类型,可能会在QASM转化成量子程序的过程中发生错误。

QASM(Quantum Assembly Language)是IBM公司提出的量子汇编语言,与 QRunes介绍 中的语法规则类似,一段QASM代码如下所示:

OPENQASM 2.0;
include "qelib1.inc";
qreg q[10];
creg c[10];

x q[0];
h q[1];
tdg q[2];
sdg q[2];
cx q[0],q[2];
cx q[1],q[4];
u1(pi) q[0];
u2(pi,pi) q[1];
u3(pi,pi,pi) q[2];
cz q[2],q[5];
ccx q[3],q[4],q[6];
cu3(pi,pi,pi) q[0],q[1];
measure q[2] -> c[2];
measure q[0] -> c[0];

需要注意的是,QASM的语法格式与QRunes形相似而神不同,主要区别有以下几点:

  • QRunes对于需要进行转置共轭操作的量子逻辑门与量子线路,需要将目标置于DAGGER与ENDAGGER语句之间,而QASM会直接进行转化。

  • QRunes支持对量子逻辑门与量子线路施加控制操作,而QASM不支持,在对量子程序转化QASM指令集之前,会对其中包含的控制操作进行分解。

QPanda2提供了QASM转换工具接口 convert_qprog_to_qasm 该接口使用非常简单。

convert_qprog_to_qasm(qprog: QProg, machine: QuantumMachine) str

该函数将给定的量子程序转换为 QASM 指令字符串。QASM 是一种用于描述量子程序的文本格式,可以用于与其他量子计算平台进行交互和兼容。

参数:
  • qprog (QProg) -- 要转换的量子程序。

  • machine (QuantumMachine) -- 用于转换的量子机器。

返回:

存储转换后 QASM 指令的字符串。

返回类型:

str

抛出:

run_fail -- 转换量子程序为 QASM 失败。

示例用法:

# 创建一个量子机器
qvm = CPUQVM()
qvm.init_qvm()

# 创建一个量子程序
prog = QProg()

# 将量子程序转换为 QASM 指令字符串
qasm_string = convert_qprog_to_qasm(prog, qvm)

下面的例程通过简单的接口调用演示了量子程序转化QASM指令集的过程

from pyqpanda import *

if __name__ == "__main__":
    qvm = CPUQVM()
    qvm.init_qvm()
    q = qvm.qAlloc_many(6)
    c = qvm.cAlloc_many(6)
    prog = QProg()
    cir = QCircuit()
    cir << T(q[0]) << S(q[1]) << CNOT(q[1], q[0])
    prog << cir
    prog << X(q[0]) << Y(q[1]) << CU(1.2345, 3, 4, 5, q[5], q[2])\
        << H(q[2]) << RX(q[3], 3.14)\
        << Measure(q[0], c[0])

    qasm = convert_qprog_to_qasm(prog, qvm)
    print(qasm)
    qvm.finalize()

具体步骤如下:

  • 首先在主程序中用 init_quantum_machine 初始化一个量子虚拟机对象,用于管理后续一系列行为。

  • 接着用 qAlloc_manycAlloc_many 初始化量子比特与经典寄存器数目。

  • 然后调用 QProg 构建量子程序。

  • 最后调用接口 convert_qprog_to_qasm 输出QASM指令集。finalize() 用于释放系统资源。

运行结果如下:

OPENQASM 2.0;
include "qelib1.inc";
qreg q[6];
creg c[6];
u3(0,0.78539816339744828,0) q[0];
u3(0,1.5707963267948966,0) q[1];
cx q[1],q[0];
u3(3.1415926535897931,0,3.1415926535897931) q[0];
u3(3.1415926535897931,0,0) q[1];
u3(0,-0.33629632679489674,0) q[5];
u3(1.5707963267948968,0,2.4689999999999994) q[2];
cz q[5],q[2];
u3(0.33629632679489924,-1.5707963267948966,1.5707963267948966) q[2];
cz q[5],q[2];
u3(1.1586360625022274,0.30011082466761058,-0.12333631564044467) q[2];
u3(0,1.5707963267948963,0) q[5];
cz q[5],q[2];
u3(1.4173486819813736,2.7391542832240892,-1.915529794610245) q[2];
cz q[5],q[2];
u3(1.8052963267948967,-1.5707963267948966,1.5707963267948966) q[2];
u3(3.1400000000000001,-1.5707963267948966,1.5707963267948966) q[3];
measure q[0] -> c[0];

Quil

简介

Quil可以从一个很低级的层次直接描述量子程序、量子算法,它的地位类似于经典计算机中的硬件描述语言或者汇编语言。Quil基本采用“指令+参数列表”的设计方法。一个简单的量子程序例子如下:
X 0
Y 1
CNOT 0 1
H 0
RX(-3.141593) 0
MEASURE 1 [0]
  • X 的作用是对目标量子比特进行 Pauli-X 门操作。与之类似的关键词有 YZH 等等。

  • Y 的作用是对目标量子比特进行 Pauli-Y 门操作。

  • CNOT 的作用是对两个量子比特执行 CNOT 操作。输入参数为控制量子比特序号和目标量子比特序号。

  • H 的作用是对目标量子比特进行 Hadamard 门操作。

  • MEASURE 的作用对目标量子比特进行测量并将测量结果保存在对应的经典寄存器里面,输入参数为目标量子比特序号和保存测量结果的经典寄存器序号。

上述仅为Quil指令集语法的一小部分, 详细介绍请参考 pyQuil

接口介绍

convert_qprog_to_quil(qprog: QProg, machine: QuantumMachine) str

将 QProg 转换为 Quil 指令字符串

该函数用于将QProg转化为 Quil(Quantum Instruction Language)指令字符串。Quil 是一种量子程序语言,用于描述量子线路的操作和演化。

param qprog:

要转换的 Quantum Program(QProg)。

type qprog:

QProg

param machine:

量子计算机实例,用于提供上下文环境。

type machine:

QuantumMachine

return:

Quil 指令字符串。

rtype:

str

示例用法:

quil_code = convert_qprog_to_quil(qprog, machine)  # 将 QProg 转化为 Quil 指令字符串

我们先用pyqpanda构建一个量子程序:

prog = QProg()
prog << X(qubits[0]) << Y(qubits[1])\
    << H(qubits[2]) << RX(qubits[3], 3.14)\
    << Measure(qubits[0], cbits[0])

然后调用 convert_qprog_to_quil 接口实现转化

quil = convert_qprog_to_quil(prog, qvm)

实例

from pyqpanda import *

if __name__ == "__main__":
    qvm = CPUQVM()
    qvm.init_qvm()
    qubits = qvm.qAlloc_many(4)
    cbits = qvm.cAlloc_many(4)
    prog = QProg()

    # 构建量子程序
    prog << X(qubits[0]) << Y(qubits[1])\
        << H(qubits[2]) << RX(qubits[3], 3.14)\
        << Measure(qubits[0], cbits[0])

    # 量子程序转换Quil, 并打印Quil
    quil = convert_qprog_to_quil(prog, qvm)
    print(quil)

运行结果:

DECLARE ro BIT[1]
X 0
Y 1
H 2
RX(3.140000) 3
MEASURE 0 ro[0]

量子体积

简介

量子体积(Quantum Volume)[1],是一个用于评估量子计算系统性能的协议。它表示可以在系统上执行的最大等宽度深度的随机线路。量子计算系统的操作保真度越高,关联性越高,有越大的校准过的门操作集合便会有越高的量子体积。量子体积与系统的整体性能相关联,即与系统的整体错误率,潜在的物理比特关联和门操作并行度相联系。总的来说,量子体积是一个用于近期整体评估量子计算系统的一个实用方法,数值越高,系统整体错误率就越低,性能就越好。

测量量子体积的标准做法就是对系统使用规定的量子线路模型执行随机的线路操作,尽可能地将比特纠缠在一起,然后再将实验得到的结果与模拟的结果进行比较。按要求分析统计结果。

量子体积被定义为指数形式:

\[V_Q=2^n\]

其中n表示在给定比特数目m(m大于n)和完成计算任务的条件下,系统操作的最大逻辑深度,如果芯片能执行的最大逻辑深度n大于比特数m,那么系统的量子体积就是

\[2^m\]

接口说明

calculate_quantum_volume(config: QCloudTaskConfig, qubit_list: List[List[int]], ntrials: int) int

此函数用于计算量子体积。

参数:
  • config (QCloudTaskConfig) -- QCloudTaskConfig 对象,表示云量子任务的配置。

  • qubit_list (List[List[int]]) -- 包含量子比特索引的列表,用于定义量子电路的结构。

  • ntrials (int) -- 执行量子体积计算的实验次数。

返回:

计算得到的量子体积。

返回类型:

int

抛出:

run_fail -- 计算量子体积失败。

实例

from pyqpanda import *

if __name__=="__main__":

    #构建待测量的量子比特组合, 这里比特组合为2组,其中 量子比特31、31为一组;量子比特0,6,12为一组
    qubit_lists = [[31, 32], [0, 6, 12]]

    #设置随机迭代次数
    ntrials = 10

    #设置用户真实apikey,需要确保有足够算力资源
    online_api_key = "XXX"

    #配置量子计算任务参数
    config = QCloudTaskConfig()
    config.cloud_token = online_api_key
    config.chip_id = origin_72
    config.open_amend = False
    config.open_mapping = False
    config.open_optimization = False
    config.shots = 1000

    qv_result = calculate_quantum_volume(config, qubit_lists, ntrials)
    print("Quantum Volume : ", qv_result)

    #运行结果:
    # Quantum Volume : 4

参考文献

[1] Andrew W. Cross, Lev S. Bishop, Sarah Sheldon, Paul D. Nation, and Jay M. Gambetta, Validating quantum computers using randomized model circuits, Phys. Rev. A 100, 032328 (2019). https://arxiv.org/pdf/1811.12926

随机基准

简介

随机基准测试(Randomized Benchmarking,RB)是量子计算中一种用于量子门性能评估的实验技术。它用于测量量子门的错误率,提供了关于量子计算系统的噪声水平和稳定性的信息。RB 是一种广泛使用的方法,用于评估量子设备的可靠性和错误率。

算法流程

在随机基准测试中,主要思想是通过对随机序列的一系列量子门操作进行测量,来评估量子门的错误率。这些随机序列的特点是它们会趋向于互相抵消,从而减少系统噪声的影响。通过比较实际测量结果和理论预期,可以估计出量子门的错误率。

实验过程如下:

  1. 生成随机序列:生成一系列随机的量子门序列,这些序列涵盖了不同的量子门操作和顺序。

  2. 实验操作:在量子设备上依次执行生成的随机序列。

  3. 测量结果:对每个随机序列,测量量子比特的状态,并记录测量结果。

1,2,3步的具体操作如下:

1,2,3步的具体操作

在Clifford群中随机需求m个门,构成一个序列; 计算该序列的等效 \(U\) 操作,该操作的逆 \(\mathrm{U}^{-1}\) 一定也在Clifford群中,将 \(\mathrm{U}^{-1}\) 添加到序列中作为第m+1个元素,构成一个完整的序列; 测量量子比特在该序列操作之后的0态(初态在0态)保真度 \(y_{mk}\)

  1. 分析:通过比较预期测量结果和实际测量结果,可以得出量子门的错误率。通常使用指数递减模型来分析错误率。

  2. 错误率估计:通过分析获得的数据,可以估计出不同量子门的平均错误率。

4,5步的具体操作

计算序列长度为m时的平均保真度 \(y_m=\frac{1}{K} \sum_1^K y_{m k}\) , 得到序列平均保真度y和序列长度m的关系,并用公式下面拟合:

\[\begin{aligned} y=A * p^m+B \end{aligned}\]

门操作平均错误率 \(r_c\) 与拟合参数𝑝的关系:

\[\begin{aligned} r_c=(1-p) *\left(2^n-1\right) / 2^n \end{aligned}\]

随着Clifford门数量的增加,门序列的平均成功概率会下降,因为当重复应用包含错误的量子门时,整个门序列的错误概率会单调增加,在 RB 中,通常假设不同Clifford的噪声超算子相等,在此假设下,门序列的平均成功概率已被证明随Clifford门的数量呈指数衰减。

接口说明

1.单门随机基准测试: single_qubit_rb

single_qubit_rb(config: QCloudTaskConfig, qubit: int, clifford_range: List[int], num_circuits: int, interleaved_gates: List[QGate] = []) Dict[int, float]

此函数用于执行单比特随机电路基准(Single Qubit Randomized Benchmarking)实验。

参数:
  • config (QCloudTaskConfig) -- QCloudTaskConfig 对象,表示云量子任务的配置。

  • qubit (int) -- 单比特量子比特索引。

  • clifford_range (List[int]) -- 包含 Clifford 门的序列长度范围的列表,用于指定不同长度的 Clifford 门序列。

  • num_circuits (int) -- 要执行的电路数量。

  • interleaved_gates (List[QGate], optional) -- 包含插入在 Clifford 门序列中的额外门的列表,默认为空列表。

返回:

包含单比特随机电路基准实验结果的字典,其中键是 Clifford 门序列长度,值是误差概率。

返回类型:

Dict[int,float]

抛出:

run_fail -- 执行单比特随机电路基准实验失败。

2.双门随机基准测试: double_qubit_rb

double_qubit_rb(config: QCloudTaskConfig, qubit0: int, qubit1: int, clifford_range: List[int], num_circuits: int, interleaved_gates: List[QGate] = []) Dict[int, float]

此函数用于执行双比特随机电路基准(Double Qubit Randomized Benchmarking)实验。

参数:
  • config (QCloudTaskConfig) -- QCloudTaskConfig 对象,表示云量子任务的配置。

  • qubit0 (int) -- 双比特第一个量子比特索引。

  • qubit1 (int) -- 双比特第二个量子比特索引。

  • clifford_range (List[int]) -- 包含 Clifford 门的序列长度范围的列表,用于指定不同长度的 Clifford 门序列。

  • num_circuits (int) -- 要执行的电路数量。

  • interleaved_gates (List[QGate], optional) -- 包含插入在 Clifford 门序列中的额外门的列表,默认为空列表。

返回:

包含双比特随机电路基准实验结果的字典,其中键是 Clifford 门序列长度,值是误差概率。

返回类型:

Dict[int,float]

抛出:

run_fail -- 执行双比特随机电路基准实验失败。

实例

from pyqpanda import *

if __name__=="__main__":

    # 设置随机线路中clifford门集数量
    range = [ 5,10,15 ]

    #设置用户真实apikey,需要确保有足够算力资源
    online_api_key = "XXX"

    #配置量子计算任务参数
    config = QCloudTaskConfig()
    config.cloud_token = online_api_key
    config.chip_id = origin_72
    config.open_amend = False
    config.open_mapping = False
    config.open_optimization = False
    config.shots = 1000

    #测量单比特随机基准
    single_rb_result = single_qubit_rb(config, 0, range, 20)

    #同样可以测量两比特随机基准
    double_rb_result = double_qubit_rb(config, 0, 1, range, 20)

    #对应的数值随设备噪声影响,噪声数值越大,所得结果越小,且随clifford门集数量增多,结果数值越小。
    print(single_rb_result)
    print(double_rb_result)

    #运行结果:
    # {5: 0.464, 10: 0.4535, 15: 0.437}
    # {5: 0.1675, 10: 0.20750000000000002, 15: 0.198}

参考文献

[1] Easwar Magesan, J. M. Gambetta, and Joseph Emerson, Robust randomized benchmarking of quantum processes, https://arxiv.org/abs/1009.3639.
[2] Easwar Magesan, Jay M. Gambetta, and Joseph Emerson, Characterizing Quantum Gates via Randomized Benchmarking, https://arxiv.org/abs/1109.6887.

交叉熵基准

简介

交叉熵基准测试(xeb)[1]是一种通过应用随机电路并测量观察到的位串测量值与从模拟获得的这些位串的预期概率之间的交叉熵来评估门性能的方法。

原理

XEB 实验收集了执行随机电路时受到噪声影响的数据。应用带有单元 U 的随机电路的效果被模拟为去极化通道。其结果是,初始状态 \(\left|\psi\right\rangle\) 映射到密度矩阵 \(\rho_U\) 如下

\[\begin{aligned} \left|\psi\right\rangle \to \rho_U = f \left|\psi_U\right\rangle \left\langle\psi_U\right| + (1 - f) I / D \end{aligned}\]

其中, \(\left|\psi_U\right\rangle = U\left|\psi\right\rangle\) , \(D\) 是希尔伯特空间的维度, \(I/D\) 是最大混合状态, \(f\) 是电路应用的保真度。 要使这一模型准确无误,我们需要一个 \(U\) 能扰乱错误的随机电路。在实践中,我们使用了一种特殊的电路范式,由随机单量子比特旋转与纠缠门交错组成。 这里引入能表示所有概率之和的观测值 \(O_U\) ,例如: \(O_U|x\rangle = p(x)|s\rangle\) ,对于任意的位字符串 \(x\) ,我们可以根据如下公式及进行推导:

\[\begin{split}\begin{aligned} e_U &= \langle \psi_U|O_U|\psi_U\rangle \\ &= \sum_{x} a^{*}_x \langle x |O_U|x\rangle a_x \\ &= \sum_{x} a^{*}_x p(x) \langle x|O_U|x \rangle \\ &= \sum_{x} a^{*}_x p(x)p(x) \end{aligned}\end{split}\]

其中 \(e_U\) 是理想概率的平方和。 \(u_U\) 是一个只取决于算子的归一化因子。由于该算子的定义中包含了真实概率,因此在这里会显示出来。

\[\begin{split}\begin{aligned} u_U &= Tr[O_U / D ] \\ &= 1/D \sum_{x} \langle x |O_U|x\rangle \\ &= 1/D \sum_{x} p(x) \end{aligned}\end{split}\]

假设观测值 \(O_U\) 在计算基础中是对角线。则 \(O_U\)\(\rho_U\) 上的期望值为

\[\begin{aligned} Tr(\rho_U O_U) = f\langle\psi_U|O_U|\psi_U\rangle + (1-f)Tr(O_U/D) \end{aligned}\]

这个等式说明了 \(f\) 的估算方式,因为 \(Tr(\rho_U O_U)\) 可以根据实验数据估算,并且 \(\langle\psi_U|O_U|\psi_U\rangle 和 Tr(O_U/D)\) 可以通过计算求出。 让 \(e_U = \langle\psi_U|O_U|\psi_U\rangle, u_U = Tr(O_U/D)\) , 定义 \(m_U为Tr(\rho_U O_U)\) 的实验估计值。上述的表达式可以转化为以下的线性方程。

\[\begin{split}\begin{aligned} & m_U=f e_U+(1-f) u_U \\ & m_U-u_U=f\left(e_U-u_U\right) \end{aligned}\end{split}\]

核心思想

交叉熵基准测试的核心思想是比较量子计算机在理论预期和实际运行中的行为之间的差异。具体而言,通过在理论上准备一系列特定的量子态并在量子计算机上执行相应的门操作,然后测量产生的量子态与预期状态之间的交叉熵,可以得出量子计算机的性能评估结果。交叉熵是一种在信息论中常用的度量,用于衡量两个概率分布之间的差异。

接口说明

double_gate_xeb(config: QCloudTaskConfig, qubit0: int, qubit1: int, clifford_range: List[int], num_circuits: int, gate_type: GateType = GateType.CZ_GATE) Dict[int, float]

此函数用于执行双比特交叉熵基准(Double Gate XEB)实验。

参数:
  • config (QCloudTaskConfig) -- QCloudTaskConfig 对象,表示云量子任务的配置。

  • qubit0 (int) -- 双比特门的第一个量子比特索引。

  • qubit1 (int) -- 双比特门的第二个量子比特索引。

  • clifford_range (List[int]) -- 包含 Clifford 门的序列长度范围的列表,用于指定不同长度的 Clifford 门序列。

  • num_circuits (int) -- 要执行的电路数量。

  • gate_type (GateType, optional) -- 双比特门类型,默认为 CZ_GATE。

返回:

包含双比特门交叉熵基准实验结果的字典,其中键是 Clifford 门序列长度,值是误差概率。

返回类型:

Dict[int,float]

抛出:

run_fail -- 执行双比特门交叉熵基准实验失败。

实例

from pyqpanda import *

if __name__=="__main__":

    # 设置不同层数组合
    range = [2,4,6,8,10]
    # 现在可测试双门类型主要为 CZ CNOT SWAP ISWAP SQISWAP

    #设置用户真实apikey,需要确保有足够算力资源
    online_api_key = "XXX"

    #配置量子计算任务参数
    config = QCloudTaskConfig()
    config.cloud_token = online_api_key
    config.chip_id = origin_72
    config.open_amend = False
    config.open_mapping = False
    config.open_optimization = False
    config.shots = 1000

    res = double_gate_xeb(config, 0, 1, range, 20, GateType.CZ_GATE)
    # 对应的数值随噪声影响,噪声数值越大,所得结果越小,且层数增多,结果数值越小。

参考文献

[1] Boixo, S., Isakov, S.V., Smelyanskiy, V.N. et al. Characterizing quantum supremacy in near-term devices. Nature Phys 14, 595–600 (2018). https://doi.org/10.1038/s41567-018-0124-x

量子相位估计

经典形式的量子相位估计QPE (Quantum Phase Estimation) 是在QFT的基础上构造的,QPE可以计算给定幺正算符U的特征值的相位,即求解 \(U\left|\psi\right\rangle= \ e^{2\pi i\varphi}\left|\psi\right\rangle\) 中的 \(\varphi\),此处 \(\left|\psi\right\rangle\) 为U的特征向量。

QPE过程也可以表示为

\[\begin{aligned} {\rm QPE}({\rm U},|0\rangle_n|\psi\rangle_m)=|\tilde{\theta}\rangle_n|\psi\rangle_m. \end{aligned}\]

其中 \(\tilde{\theta}\)\(2^n\theta\) 在二进制下的 \(n\) 位近似。

量子线路结构概览

假设已经构造好特征向量 \(\left|\psi\right\rangle\),量子相位估计包含如下步骤:

  1. 通过一系列特殊旋转量子门操作将U的特征值相位分解转移到辅助量子比特的振幅上;

  2. 对辅助量子比特执行IQFT,将振幅上的特征值相位转移到基向量上;

  3. 对辅助量子比特的基向量分别进行测量后综合可得到特征值的相位信息。

对于幺正算符 \(U\) 的一个特征量子态 \(\left|\psi\right\rangle\),可以通过特定的量子门组合将该量子态对应的特征值相位提取到振幅,但量子态的振幅难以有效准确地测量。

必须借助其他量子门组合将特征值相位数据进行整合,最终通过IQFT可以由振幅到基向量进行数据转化的功能将特征值转移到基向量中。

备注

量子相位估计本质上是为了提取幺正算符的特征值相位,并以便于测量的形式输出。

量子线路构建

特征量子态与特征值相位提取

由特征量子态的定义有 \(U\left|\psi\right\rangle = e^{2\pi i\varphi}\left|\psi\right\rangle\),于是由幺正算符 \(U\) 可以定义受控量子门 \((C-U)\) 使得

\[\begin{aligned} (C-U^{2^t})(a\left|0\right\rangle+b\left|1\right\rangle)\otimes\left|\psi\right\rangle \ =(a\left|0\right\rangle+e^{2\pi i\varphi2^t}b\left|1\right\rangle)\otimes\left|\psi\right\rangle. \end{aligned}\]

特征值相位 \(\varphi\) 通过这种受控变换可以提取到振幅中。

特征值相位由振幅转移到基向量

选取一组初始化为最大叠加态的辅助比特,通过受控量子门可以将特征值相位提取到振幅中:

\[(C-U^{2^0})\cdots(C-U^{2^n})\frac{1}{2^\frac{n}{2}}\otimes_{t=1}^n (\left|0\right\rangle+\left|1\right\rangle)= (\left|0\right\rangle+e^{2\pi i\varphi2^{1-1}}\ \left|1\right\rangle)\cdots(\left|0\right\rangle+e^{2\pi i\varphi2^{n-1}}\left|1\right\rangle).\]

此时辅助比特中的量子态形式与QFT的结果量子态相近,借助IQFT有如下结果:

\[\begin{split}\begin{aligned} & QFT^{-1}\frac{1}{2^\frac{n}{2}}\otimes_{t=1}^n(\left|0\right\rangle+e^{2\pi i\varphi2^{t-1}} \left|1\right\rangle) \\ & =QFT^{-1}\frac{1}{2^\frac{n}{2}}\Sigma_{k=0}^{2^n-1}e^{2\pi i \varphi k}\left|k\right\rangle \\ & =\frac{1}{2^n}\Sigma_{k=0}^{2^n-1}\Sigma_{x=0} ^{2^n-1}e^{-\frac{2\pi ik}{2^n}\left(x-2^n\varphi\right)}\left|x\right\rangle. \end{aligned}\end{split}\]

含特征值相位的基向量测量

对得到的结果量子态进行测量,结果可以分为两类:

  1. 如果存在正整数 \(2^n\varphi\in \mathbb{Z}\),则可以以概率 \(1\) 测量得到 \(\left|x\right\rangle=\left|2^n\varphi\right\rangle\)

  2. 否则以至少概率 \(\frac{4}{\pi^2}\) 得到最接近 \(2^n\varphi\) 的整数,进而得到近似解

备注

如何从最接近 \(2^n\varphi\) 的整数反推得到 \(\varphi\) ?(提示:连续分数展开)

测量结果得到的是相位 \(\varphi\) 的近似解,近似解的精度与辅助比特的数目 \(n\) 相关。\(2^n\varphi\in \mathbb{Z}\) 的情况代表辅助比特的数目已经大于 \(\varphi\) 的二进制展开小数位数,因此才能得到精确解。

量子线路图与代码实现

QPE的量子线路图如下所示

_images/QPE.png

由上文中的定义,我们可以基于QPanda-2.0直接给出QPE的函数实现。

量子线路总共可以分为三个部分,特征量子态制备与辅助比特量子态初始化、特征值相位提取、逆量子傅里叶变换。程序实现的核心内容如下:

import pyqpanda as pq
from numpy import pi
import numpy as np

def QPE(controlqlist, targetqlist, matrix):
   circ = pq.QCircuit()
   for i in range(len(controlqlist)):
            circ.insert(pq.H(controlqlist[i]))

   for i in range(len(controlqlist)):
            circ.insert(pq.control_unitary_power(targetqlist, controlqlist[controlqlist.size() \
            - 1 - i], i, matrix))

   circ.insert(pq.QFT(controlqlist).dagger())
   return circ

图中的参数matrix是指需要估计特征值的幺正算符 \(U\) 对应的矩阵。

选取 \(U=RY(\frac{\pi}{4}),\left|\psi\right\rangle=\left|0\right\rangle+i\left|1\right\rangle\) , 对应的特征值为 \(e^{-i\frac{\pi}{8}}\) ,验证QPE的代码实例如下

import pyqpanda as pq
from numpy import pi

if __name__ == "__main__":

   machine = pq.init_quantum_machine(pq.QMachineType.CPU)
   qvec = machine.qAlloc_many(1)
   cqv = machine.qAlloc_many(4)
   prog = pq.create_empty_qprog()

   # 构建量子程序
   prog.insert(pq.H(cqv[0]))\
       .insert(pq.H(cqv[1]))\
       .insert(pq.H(cqv[2]))\
       .insert(pq.H(cqv[3]))\
       .insert(pq.H(qvec[0]))\
       .insert(pq.S(qvec[0]))\
       .insert(pq.RY(qvec[0], pi/4).control(cqv[0]))\
       .insert(pq.RY(qvec[0], pi/2).control(cqv[1]))\
       .insert(pq.RY(qvec[0], pi).control(cqv[2]))\
       .insert(pq.RY(qvec[0], pi*2).control(cqv[3])) \
       .insert(pq.QFT(cqv).dagger())

   # 对量子程序进行概率测量
   result = pq.prob_run_dict(prog, cqv, -1)
   pq.destroy_quantum_machine(machine)

   # 打印测量结果
   for key in result:
       print(key+":"+str(result[key]))

由前文可知输出结果应当以接近 \(1\) 的概率得到量子态 \(\left|1111\right\rangle\) (即 \(-1\)

0000:8.027759204248868e-34
0001:1.4038818472306108e-33
0010:6.324302228415449e-35
0011:1.8002817275101533e-33
0100:1.1716099389234709e-34
0101:3.7184613996614186e-35
0110:7.14619905441006e-35
0111:3.163946664340403e-33
1000:1.1716099389234709e-34
1001:2.361635369532623e-33
1010:6.324302228415447e-35
1011:1.5092886417824937e-32
1100:2.0191804511467995e-34
1101:2.142003975785634e-33
1110:1.0410679182118513e-33
1111:0.999999999999936

量子傅里叶变换

量子傅里叶变换(QFT)实质上是经典的逆离散傅里叶变换(IDFT)的量子版本。

量子傅里叶变换可以将存在于基向量中的数据与振幅中的数据在一定条件下相互转换。

如图所示,QFT可以简单地通过对IDFT进行替换得到,QFT和DFT本质上都是同一个向量在两个等价空间中的不同表示形式,即基向量的更换。

_images/QFT.png
\[\begin{split}\begin{aligned} y_k\rightarrow\frac{1}{\sqrt N}\Sigma_{j=0}^{N-1}x_j \ e^{\frac{2\pi\ i}{N}jk},\\ \left|x\right\rangle\rightarrow \ \frac{1}{2^\frac{n}{2}}\Sigma_{k=0}^{2^n-1}e^{\frac{2\pi i}{2^n} \ xk}\left|k\right\rangle. \end{aligned}\end{split}\]

由定义可知,空间 \(span\{\left|x\right\rangle\}\) 中的某个向量 \(\Sigma_x\alpha_x\left|x\right\rangle\) 通过傅里叶变换可以表示为另一个等价空间 \(span\{\left|k\right\rangle\}\) 中基向量的线性组合\(\Sigma_k\beta_k\left|k\right\rangle\), 且线性组合的系数 \(\beta_k\)\(\left|x\right\rangle\)\(\alpha_x\) 决定。

备注

量子傅里叶变换/逆变换,实质上可以视为一种振幅和基向量的相互转化。

量子线路构造

对QFT的量子线路实现需要对其表达式进行变形,得到可以用现有普适量子门组合实现的变换过程。

对任给整数 \(x\) ,由二进制展开 \(k=\Sigma_{i=1}^nk_i2^{n-i}\),对\(\left|x\right\rangle\) 进行量子傅里叶变换的结果可表示为

\[\begin{split}\begin{aligned} & QFT(\left|x\right\rangle)=\frac{1}{2^\frac{n}{2}}\Sigma_{k=0}^{2^n-1}e^\frac{2\pi ixk}{2^n} \ \left|k\right\rangle=\frac{1}{2^\frac{n}{2}}\Sigma_{k_1=0}^1\cdots\Sigma_{k_n=0}^1 \ e^{2\pi ixk\left(\Sigma_{l=1}^nk_l2^{-l}\right)}\left|k_1\cdots k_n\right\rangle \\ & =\frac{1}{2^\frac{n}{2}}\Sigma_{k_1=0}^1\cdots\Sigma_{k_n=0}^1\otimes_{l=1}^n e^{2\pi ix k_l2^{-l}} \left|k_l\right\rangle=\frac{1}{2^\frac{n}{2}}\otimes_{l=1}^n(\left|0\right\rangle+e^{2\pi ix2^{-l}} \ \left|1\right\rangle). \end{aligned}\end{split}\]

由上式可知,QFT可以将特定量子态 \(\left|x\right\rangle\) 表示为另一组基的线性组合,而这个线性组合还能表示为多个单比特量子态\(\frac{1}{\sqrt{2}}(\left|0\right\rangle + e^{2\pi ix2^{-l}}\left|1\right\rangle)\) 的张量积。

因此对任给整数 \(x\),如果可以由二进制展开位 \(\left|x_{n+1-l}\right\rangle\) 快速构造量子态 \(\frac{1}{\sqrt{2}}(\left|0\right\rangle + e^{2\pi ix2^{-l}}\left|1\right\rangle)\),那么就可以通过张量积形式的QFT表达式完成相应QFT量子线路的构造。

任给整数 \(x\) 进行二进制展开近似:

\[\begin{aligned} x/2^m \approx \left[x_1\cdots x_m\right]/2^m=\left[0.x_1\cdots x_m\right]=\Sigma_{k=1}^mx_k2^{-k}, \end{aligned}\]

\[\begin{aligned} 2\pi ix2^{-l}=2\pi i\left[x_1\cdots x_n\right]2^{-l}=2\pi i\left[0.x_{n-l}\cdots x_n\right]. \end{aligned}\]

于是制备 \(\frac{1}{\sqrt{2}}(\left|0\right\rangle + e^{2\pi ix2^{-l}}\left|1\right\rangle)\) 转化为制备 \(\frac{1}{\sqrt{2}}(\left|0\right\rangle + e^{2\pi i [0.x_{n-l}\cdots x_n]}\left|1\right\rangle)\)

注意到 \(H\left|0\right\rangle = \frac{1}{\sqrt{2}}(\left|0\right\rangle + \left|1\right\rangle) = \ \frac{1}{\sqrt{2}}(\left|0\right\rangle + e^{2\pi i [0.x_n]}\left|1\right\rangle)\) ,而

\[\begin{split}\begin{aligned} & \frac{1}{\sqrt{2}}(\left|0\right\rangle + e^{2\pi i [0.x_{n-1} x_n]}\left|1\right\rangle) = \ \frac{1}{\sqrt{2}}(\left|0\right\rangle + e^{2\pi i [0.x_{n-1}]} e^{2\pi i [0.0 x_n]} \left|1\right\rangle),\\ & R_m \left|0\right\rangle = \left|0\right\rangle, R_m \left|1\right\rangle = e^{2\pi i \frac{1}{2^m}}\left|1\right\rangle. \end{aligned}\end{split}\]

定义受控旋转量子门 \((C-R)_{j-k+1}\) 满足

\[\begin{aligned} (C-R)_{j-k+1} \frac{1}{\sqrt{2}}(\left|0\right\rangle + e^{2\pi i [0.x_{n-j}]} \left|1\right\rangle)\left|x_{n-k}\right\rangle = \frac{1}{\sqrt{2}}( \left|0\right\rangle + e^{2\pi i [0.x_{n-j}0\cdots 0x_{n-k}]}\left|1\right\rangle. \end{aligned}\]

于是利用量子门 \(H\)\((C-R)_{j-k+1}\) 就可以完成对量子态\(\frac{1}{\sqrt{2}}(\left|0\right\rangle + e^{2\pi ix2^{-l}}\left|1\right\rangle)\)的制备,进而完成QFT的量子线路。

QFT的量子线路图如下所示

_images/QFT.png

特别地,注意到上图中初始量子态为 \(\left|x_i\right\rangle\) 的量子比特对应的结果量子态为\(\frac{1}{\sqrt{2}}(\left|0\right\rangle + e^{2\pi ix2^{n+1-l}}\left|1\right\rangle)\)而非 \(\frac{1}{\sqrt{2}}(\left|0\right\rangle + e^{2\pi ix2^{-l}}\left|1\right\rangle)\) ,因此实际使用时还需要追加相应的多组 \(SWAP\) 门。

代码实现

QFT在一维情况就是Hadamard量子门。 基于QPanda-2.0的QFT接口函数如下:

QFT(qlist)

选取 \(\left|x\right\rangle=\left|000\right\rangle\) 验证QFT的代码实例如下

#!/usr/bin/env python

import pyqpanda as pq
from numpy import pi

if __name__ == "__main__":

    machine = pq.init_quantum_machine(pq.QMachineType.CPU)
    qvec = machine.qAlloc_many(3)
    prog = pq.create_empty_qprog()

    # 构建量子程序
    prog.insert(pq.QFT(qvec))

    # 对量子程序进行概率测量
    result = pq.prob_run_dict(prog, qvec, -1)
    pq.destroy_quantum_machine(machine)

    # 打印测量结果
    for key in result:
         print(key+":"+str(result[key]))

由前文中QFT的定义及 \(\left|x\right\rangle=\left|000\right\rangle\) 可知输出结果应当以均匀概率 \(\frac{1}{8}\) 得到所有量子态,即

000:0.125
001:0.125
010:0.125
011:0.125
100:0.125
101:0.125
110:0.125
111:0.125

优化算法(直接搜索法)

本章节将讲解优化算法的使用,包括 Nelder-Mead 算法跟 Powell 算法,它们都是一种直接搜索算法。我们在 QPanda 中实现了这两个算法,OriginNelderMeadOriginPowell , 这两个类都继承自 AbstractOptimizer

我们可以通过优化器工厂生成指定类型的优化器,例如我们指定它的类型为Nelder-Mead

optimizer = OptimizerFactory.makeOptimizer(OptimizerType.NELDER_MEAD)
#optimizer = OptimizerFactory.makeOptimizer('Nelder-Mead')

我们需要向优化器注册一个计算损失值的函数和待优化参数。

init_para = [0, 0]
optimizer.registerFunc(lossFunc, init_para)

然后设置结束条件,我们可以设置变量及函数值的收敛阈值,函数最大可调用次数,和优化迭代次数。只要满足上述结束条件,则优化结束。

optimizer.setXatol(1e-6)
optimizer.setFatol(1e-6)
optimizer.setMaxFCalls(200)
optimizer.setMaxIter(200)

然后通过exec接口执行优化,通过getResult接口获得优化后的结果。

optimizer.exec()

result = optimizer.getResult()
print(result.message)
print(" Current function value: ", result.fun_val)
print(" Iterations: ", result.iters)
print(" Function evaluations: ", result.fcalls)
print(" Optimized para: W: ", result.para[0], " b: ", result.para[1])

给定一些散列点,我们来拟合一条直线,使得散列点到直线的距离和最小。定义直线的函数的表达式为 y = w*x + b ,接下来我们将通过使用优化算法得到w和b的优化值。 首先定义求期望的函数

from pyqpanda import *
import numpy as np

x = np.array([3.3, 4.4, 5.5, 6.71, 6.93, 4.168, 9.779, 6.182, 7.59,
             2.167, 7.042, 10.791, 5.313, 7.997, 5.654, 9.27,3.1])
y = np.array([1.7, 2.76, 2.09, 3.19, 1.694, 1.573, 3.366, 2.596, 2.53,
             1.221, 2.827, 3.465, 1.65, 2.904, 2.42, 2.94,1.3])

def lossFunc(para,grad,inter,fcall):
    y_ = np.zeros(len(y))

    for i in range(len(y)):
        y_[i] = para[0] * x[i] + para[1]

    loss = 0
    for i in range(len(y)):
        loss += (y_[i] - y[i])**2/len(y)

    return ("", loss)

我们使用 Nelder-Mead 算法进行优化

optimizer = OptimizerFactory.makeOptimizer('Nelder-Mead')

init_para = [0, 0]
optimizer.registerFunc(lossFunc, init_para)
optimizer.setXatol(1e-6)
optimizer.setFatol(1e-6)
optimizer.setMaxIter(200)
optimizer.exec()

result = optimizer.getResult()
print(result.message)
print(" Current function value: ", result.fun_val)
print(" Iterations: ", result.iters)
print(" Function evaluations: ", result.fcalls)
print(" Optimized para: W: ", result.para[0], " b: ", result.para[1])
_images/OptimizerTest.png

我们将散列点和拟合的直线进行绘图

import matplotlib.pyplot as plt

w = result.para[0]
b = result.para[1]

plt.plot(x, y, 'o', label = 'Training data')
plt.plot(x, w*x + b, 'r', label = 'Fitted line')
plt.legend()
plt.show()
_images/OptimizerPlot.png

哈密顿量模拟

哈密顿量以威廉·罗文·汉密尔顿(William Rowan Hamilton)命名,他也创造了牛顿力学的革命性改革,现在称为哈米尔顿力学,这在量子物理学中是重要的。 哈密顿量是所有粒子的动能的总和加上与系统相关的粒子的势能。 对于不同的情况或数量的粒子,哈密顿量是不同的,因为它包括粒子的动能之和以及对应于这种情况的势能函数。

在量子力学中,波函数 \(\Psi( |t \rangle)\) 的时间演化由含时薛定谔方程控制。

将普朗克常量视为1,将积分上下限分别定为 t、0,并经过一系列数学运算后,可以得到 \(\Psi( |t \rangle) = e^{-iHt} \Psi( |0 \rangle)\)

哈密顿量(哈密顿算符)在数学上被表示为Hermitian矩阵,而随着qubit数量的增加,其希尔伯特空间是指数增长的,相对应的哈密顿量的维度也是呈指数增长。 因此,需要使用一些近似方法,最简单的近似方法就是在关于矩阵的泰勒展开式 \(\Psi( |t \rangle) \approx (I-iHt) \Psi( |0 \rangle)\) 通过更高阶的近似,可以得到更高的精度逼近。

step1:构造相关矩阵;

step2:构造模拟线路;

step3:使用 QOperator 操作将线路构造成算符操作,并获取线路的对应矩阵;

step4:使用 expMat() 接口计算 e 的复数矩阵的真实值;

step5:使用 average_gate_fidelity() 接口计算两个矩阵的相似度。

import math
import numpy as np
import pyqpanda as pq

if __name__ == "__main__":
    pq.init(pq.QMachineType.CPU)
    q = pq.qAlloc_many(4)

    # 构建pauli 算子
    X = np.mat([[0, 1], [1, 0]])
    Y = np.mat([[0, -1j], [1j, 0]])
    Z = np.mat([[1, 0], [0, -1]])
    t = np.pi

    circuit_x = pq.create_empty_circuit()
    circuit_y = pq.create_empty_circuit()
    circuit_z = pq.create_empty_circuit()

    # 构造Hamiltonian Operator
    circuit_x << pq.H(q[0]) \
            << pq.X(q[0]) \
            << pq.RZ(q[0], -t) \
            << pq.X(q[0]) \
            << pq.RZ(q[0], t) \
            << pq.H(q[0])

    circuit_y << pq.RX(q[0], t / 2) \
            << pq.X(q[0]) \
            << pq.RZ(q[0], -t) \
            << pq.X(q[0]) \
            << pq.RZ(q[0], t) \
            << pq.RX(q[0], -t / 2)

    circuit_z << pq.X(q[0]) \
            << pq.RZ(q[0], -t) \
            << pq.X(q[0]) \
            << pq.RZ(q[0], t)

    operator_x = pq.QOperator(circuit_x)
    operator_y = pq.QOperator(circuit_y)
    operator_z = pq.QOperator(circuit_z)

    unitary_x = operator_x.get_matrix()
    unitary_y = operator_y.get_matrix()
    unitary_z = operator_z.get_matrix()

    conf = complex(0, -1)
    U_x = pq.expMat(conf, X, t)
    U_y = pq.expMat(conf, Y, t)
    U_z = pq.expMat(conf, Z, t)

    f_ave_x = pq.average_gate_fidelity(U_x, unitary_x)
    f_ave_y = pq.average_gate_fidelity(U_y, unitary_y)
    f_ave_z = pq.average_gate_fidelity(U_z, unitary_z)

    print("Pauli-X Average Gate Fidelity: F = {:f}".format(f_ave_x))
    print("Pauli-Y Average Gate Fidelity: F = {:f}".format(f_ave_y))
    print("Pauli-Z Average Gate Fidelity: F = {:f}".format(f_ave_z))

运行结果如下:

Pauli-X Average Gate Fidelity: F = 1.000000
Pauli-Y Average Gate Fidelity: F = 1.000000
Pauli-Z Average Gate Fidelity: F = 1.000000

振幅放大

振幅放大(Amplitude Amplification)线路的主要作用为对于给定纯态的振幅进行放大,从而调整其测量结果概率分布。

算法背景

假设某个实际问题转化而来的量子模型的解为 \(|\varphi_1\rangle\),归一化的叠加态 \(|\psi\rangle\) 可由 \(|\varphi_1\rangle\) ,和它的正交量子态如下表示:\(|\psi\rangle=\sin\theta|\varphi_1\rangle+\cos\theta|\varphi_0\rangle\) 此处,\(|\varphi_0\rangle=|\varphi_1^\perp\rangle\) ,已知 \(|\psi\rangle\)\(\theta\) ,求 \(|\varphi_1\rangle\) 利用振幅放大算法可以放大上述表达式中目标基向量 \(|\varphi_{1}\rangle\) 的系数,得到形如

\[\begin{aligned} |\psi_k\rangle=\sin{k\theta}|\varphi_1\rangle+\cos{k\theta}|\varphi_0\rangle,~k\theta\approx\frac{\pi}{2} \end{aligned}\]

的量子态,此时对 \(|\psi_k\rangle\) 测量得到问题解 \(|\varphi_{1}\rangle\) 的概率被放大到约为1,因此振幅放大量子线路又被称为提取线路。

考虑一个N维Hilbert空间,存在一个自共轭投影算符 \({\rm P}:{\rm H}\mapsto{\rm H}\) 使得

\[\begin{split}{\rm P}|x\rangle= \begin{cases} |x\rangle,~x\in {\rm H_0}\\ -|x\rangle,~x\in {\rm H_1} \end{cases}\end{split}\]

其中 \({\rm H}={\rm H_0}\oplus{\rm H_1}\),要求出一个 \(x\in{\rm H_1}\).

首先构造出包含问题解的叠加态. 考虑N维量子态 \(|0\rangle_N\) ,由 \({\rm H}={\rm H_0}\oplus{\rm H_1}\) 可知存在一个不含测量的可逆量子算符 \(\mathcal{A}\) 使得

\[\begin{aligned} \mathcal{A}|0\rangle_N=|\psi\rangle=\cos\theta|\varphi_0\rangle+\sin\theta|\varphi_1\rangle \end{aligned}\]

其中 \(|\varphi_0\rangle=|\varphi_1^\perp\rangle,~\varphi_0\in{\rm H_0},~\varphi_1\in{\rm H_1}.\)

其次构造出能快速放大解 \(|\varphi_1\rangle\) 的系数的量子门. 定义幺正算符 \({\rm Q}=-({\rm I}-2|\psi\rangle\langle\psi|){\rm P}\),则有

\[\begin{aligned} {\rm Q}|\varphi_0\rangle=-({\rm I}-2|\psi\rangle\langle\psi|)|\varphi_0\rangle=\cos{2\theta}|\varphi_0\rangle+\sin{2\theta}|\varphi_1\rangle \end{aligned}\]
\[\begin{aligned} {\rm Q}|\varphi_1\rangle=({\rm I}-2|\psi\rangle\langle\psi|)|\varphi_1\rangle=-\sin{2\theta}|\varphi_0\rangle+\cos{2\theta}|\varphi_1\rangle. \end{aligned}\]

于是在 \(\{|\varphi_0\rangle,~|\varphi_1\rangle\}张成的子空间{\rm H}_{\psi}内有{\rm Q}=\begin{bmatrix} \cos{2\theta} & -\sin{2\theta} \\ \sin{2\theta} & \cos{2\theta} \end{bmatrix}\).

Q门可视为角度为 \(2\theta\) 的旋转量子门操作. 实际上若记 \({\rm P}={\rm I}-2|\varphi_1\rangle\langle\varphi_1|\) , Q门可视为对 \(|\varphi_0\rangle\) 和对 \(|\varphi_1\rangle\) 的镜像变换的组合。 \(|0\rangle_N\) 经过 \(\mathcal{A}\) 门和n次Q门旋转之后得到的量子态为

\[\begin{aligned} {\rm Q}^n|\psi\rangle=\cos{(2n+1)\theta}|\varphi_0\rangle+\sin{(2n+1)\theta}|\varphi_1\rangle. \end{aligned}\]

当选取 \(n=\lfloor\dfrac{\pi}{4\theta}\rfloor\) 时,测量量子态 \({\rm Q}^n|\psi\rangle\) 得到目标解 \(|\varphi_{1}\rangle\) 的概率 \(\sin^2{(2n+1)\theta}\) 趋于最大. 于是测量量子态 \({\rm Q}^n|\psi\rangle\) 能够以逼近 1 的概率得到问题的解.

进一步地,对振幅放大操作进行一般化推广,记

\[\begin{aligned} {\rm Q}=-\mathcal{A}S_{0}\mathcal{A}^{-1}S_{P} \end{aligned}\]

其中

\[\begin{split}\begin{aligned} S_{0}=\begin{cases} |x\rangle, ~x\in H_{0}\\ k|x\rangle, ~~x\in H_{1} \end{cases},~~ S_{P}=\begin{cases} kx, ~x=0\\ x, ~x\ne 0 \end{cases}. \end{aligned}\end{split}\]

则有

\[\begin{split}\begin{aligned} \begin{split} {\rm Q}|\varphi_0\rangle &=k(1+\cos^{2})(\theta)|\varphi_0\rangle+(1-k)\cos^{2}(\theta)|\varphi_1\rangle,\\ {\rm Q}|\varphi_1\rangle &=k(k-1)\sin^{2}(\theta)|\varphi_0\rangle+k((1-k)\sin^{2}(\theta)-1)|\varphi_1\rangle. \end{split} \end{aligned}\end{split}\]

证明的关键在于利用幺正算符 \(\mathcal{A}\) 性质得到

\[\begin{aligned} \langle \varphi|\varphi_{1}\rangle = \langle 0|\mathcal{A}^{\dagger}|\varphi_{1}\rangle= \langle 0|\mathcal{A}^{-1}|\varphi_{1}\rangle=\sin^{2}{\theta}. \end{aligned}\]

\[\begin{aligned} \mathcal{A}^{-1}|\varphi_{1}\rangle=\sin^{2}{\theta}|0\rangle+\lambda|1\rangle \end{aligned}\]

此处的 \({\rm Q}\) 为一般意义上的振幅放大算子,通过合理的选择 \(k\) ,可以得到不同的结果(比如更快的振幅放大).

代码实例

\(\Omega=\{0,1\}, \left|\psi\right\rangle = \sin{\frac{\pi}{6}}\left|1\right\rangle+ \cos{\frac{\pi}{6}}\left|0\right\rangle,\ P_1=I-2\left|1\right\rangle \left\langle 1\right|=Z, P=I-2\left|\psi\right\rangle \left\langle\psi\right|\)

振幅放大量子线路的相应代码实例如下

#!/usr/bin/env python

import pyqpanda as pq
from numpy import pi

if __name__ == "__main__":

    machine = pq.init_quantum_machine(pq.QMachineType.CPU)
    qvec = machine.qAlloc_many(1)
    prog = pq.create_empty_qprog()

    # 构建量子程序
    prog.insert(pq.RY(qvec[0], pi/3))
    prog.insert(pq.Z(qvec[0]))
    prog.insert(pq.RY(qvec[0], pi*4/3))

    # 对量子程序进行概率测量
    result = pq.prob_run_dict(prog, qvec, -1)
    pq.destroy_quantum_machine(machine)

    # 打印测量结果
    for key in result:
         print(key+":"+str(result[key]))

输出结果应如下所示,分别以 \(1\)\(0\) 的概率得到 \(\left|1\right\rangle\)\(\left|0\right\rangle\)

0:0
1:1

试验态制备与量子纠缠

试验态制备

试验态制备,指的是量子计算中任意算法的初始量子态的构造,是量子计算的初始步骤。

以单比特的两态空间为例,在实际量子运算中,我们可以直接得到的默认量子态是基态 \(\left|0\right\rangle\),通过非门可以间接得到基态 \(\left|1\right\rangle\)

对于任给的目标叠加量子态,我们则需要构造相应的量子门组合来得到。从基态 \(\left|0\right\rangle\) 出发制备任给目标叠加态的过程称为初态制备。

最大叠加态

以二比特态空间为例,从 \(\left|0\right\rangle^{\otimes2}\) 出发,对每个量子比特进行Hadamard门操作可以得到二比特空间中所有基态的均匀叠加。

类似地,在任意维态空间中,均可以借助Hadamard门从多维的 \(\left|0\right\rangle\) 基态出发,得到所有基态均匀线性组合的量子态。

这种量子态称为最大叠加态,很多量子计算中量子比特的初始状态要求为最大叠加态,量子计算的并行性也有赖于此。

通过试验态制备,我们就可以得到任意的基础量子态,从而完成量子计算中运算对象的构造。但是在执行运算操作之前,我们需要对量子计算所使用的量子比特给出明确的约束——纠缠关联。

在介绍量子纠缠之前,我们需要介绍一下纯态和混态。

纯态与混态的区分方式有多种,典型的有布洛赫球(Bloch Sphere),将态空间与Bloch球关联,球面上量子态为纯态,球体内的量子态为混态。

另一种重要的区分方式为密度矩阵,混态的密度矩阵的平方的迹小于1。

量子纠缠

如果一个量子系统的量子态 \(\left|\psi\right\rangle\) 可以表示成形如 \(\left|\psi\right\rangle=\left|\psi_0\ \right\rangle\otimes\left|\psi_1\right\rangle\) 的两个量子系统的直积形式,我们就将此量子态称为直积态。

备注

不能进行这种直积分解的量子态就是纠缠态。

例如对二比特的Bell态 \(\frac{1}{\sqrt2}\left|00\right\rangle+\frac{1}{\sqrt2}\left|11\right\rangle\),它不能写成两个单比特量子态的直积形式。

量子纠缠态有超越经典关联的量子关联。为了发挥量子计算的并行性和高效性,量子计算使用的量子比特之间应当有着纠缠关联。

最大叠加态制备

下面是基于QPanda-2.0的最大叠加态制备的代码实现,调用的量子比特之间有着纠缠关联。

#!/usr/bin/env python

import pyqpanda as pq

if __name__ == "__main__":

    machine = pq.CPUQVM()
    machine.init_qvm()
    qubits = machine.qAlloc_many(3)
    prog = pq.QProg()

    # 构建量子程序
    prog.insert(pq.H(qubits[0])) \
        .insert(pq.H(qubits[1])) \
        .insert(pq.H(qubits[2]))

    # 对量子程序进行概率测量
    result = machine.prob_run_dict(prog, qubits, -1)

    # 打印测量结果
    for key in result:
        print(key+":"+str(result[key]))

运行结果应当是以均匀概率1/8得到3比特空间中所有量子态:

000:0.125
001:0.125
010:0.125
011:0.125
100:0.125
101:0.125
110:0.125
111:0.125

量子态编码

量子态编码是一个将经典信息转化为量子态的过程。在使用量子算法解决经典问题的过程中,量子态编码是非常重要的一步。比如在使用HHL算法解如下线性方程组时

\[\begin{split}\begin{aligned} A=\left(\begin{array}{cc} 1 & -1 / 3 \\ -1 / 3 & 1 \end{array}\right), \vec{x}=\left(\begin{array}{l} x_{1} \\ x_{2} \end{array}\right), \vec{b}=\left(\begin{array}{l} 1 \\ 0 \end{array}\right) \end{aligned}\end{split}\]

需要将向量b编码至线路中。而大多数量子态编码都是以 \(\left|0\right\rangle\) 为基态进行制备,而制备后的经典信息则可以表现在量子线路的各个参数中。 本教程中我们将讨论四种量子编码的方式,包括基态编码、角度编码、振幅编码、IQP 编码。在pyqpanda中,我们内置了这四类量子编码方式至 Encode 类中。

class Encode

Encode类提供了多种量子态编码方法,用于将量子态编码为不同格式的函数,其中包括编码为二进制串的基态编码,编码至角度及相位的角度编码,以及针对稀疏数据、密集数据的多种振幅编码方式,以及近似振幅编码方法。

basic_encode(qubit, data)

基态编码[1]是将一个 \(n\) 位的二进制字符串 \(x\) 转换为一个具有 \(n\) 个量子比特的系统的量子态 \(\left|x\right\rangle=\left|\psi\right\rangle\) 其中, \(\left|\psi\right\rangle\) 为转换后的计算基态。 例如,当需要对一个长度为4的二进制字符串 \(1001\) 编码时,得到的结果即为 \(\left|1001\right\rangle\)

参数:
  • qubit (QVec) -- 编码比特列表。

  • data (str) -- 编码数据。

返回:

None

返回类型:

None

示例:

from pyqpanda import *
import numpy as np

if __name__=="__main__":

    #构建全振幅虚拟机
    qvm = CPUQVM()
    qvm.init_qvm()

    x = '1001'

    #申请量子比特
    qubits = qvm.qAlloc_many(4)

    #实例化编码类Encode
    cir_encode=Encode()

    #调用Encode类中基态编码接口
    cir_encode.basic_encode(qubits,x)

    #调用Encode类中内置获取编码线路接口
    prog = QProg()
    prog << cir_encode.get_circuit()

    #获取量子编码后的编码比特
    encode_qubits = cir_encode.get_out_qubits()

    #获取线路的概率测量结果
    result = qvm.prob_run_dict(prog, encode_qubits)

    print(result)
{'0000': 0.0, '0001': 0.0, '0010': 0.0, '0011': 0.0, '0100': 0.0, '0101': 0.0, '0110': 0.0, '0111': 0.0, '1000': 0.0, '1001': 1.0, '1010': 0.0, '1011': 0.0, '1100': 0.0, '1101': 0.0, '1110': 0.0, '1111': 0.0}
angle_encode(qubit, data, gate_type = GateType::RY_GATE)

角度编码[1]即是利用旋转门 \(R_{x}\) , \(R_{y}\) , \(R_{z}\) 的旋转角度进行对经典信息的编码。

\[\begin{aligned} |\boldsymbol{x}\rangle=\bigotimes_{i=1}^{N} \cos \left(x_{i}\right)|0\rangle+\sin \left(x_{i}\right)|1\rangle \end{aligned}\]

其中 \(\left|x\right\rangle\) 即为所需编码的经典数据向量。

参数:
  • qubit (QVec) -- 编码比特列表。

  • data (List[float]) -- 编码数据。

Parm gate_type:

编码的泡利旋转门类型,默认为 RY_GATE

返回:

None

返回类型:

None

示例:

下面我们以 \(R_{y}\) 门编码一组角度 \([\pi,\pi]\) 为例

from pyqpanda import *
import numpy as np

if __name__=="__main__":

    #构建全振幅虚拟机
    qvm = CPUQVM()
    qvm.init_qvm()
    x = [np.pi,np.pi]

    #申请量子比特
    qubits = qvm.qAlloc_many(2)

    #实例化编码类Encode
    cir_encode = Encode()

    #调用Encode类中经典角度编码或密集角度编码接口并输出概率
    cir_encode.angle_encode(qubits,x)
    prog = QProg()
    prog << cir_encode.get_circuit()
    encode_qubits=cir_encode.get_out_qubits()
    result = qvm.prob_run_dict(prog, encode_qubits)
    print(result)
    qvm.finalize()
{'00': 1.405799628556214e-65, '01': 3.749399456654644e-33, '10': 3.749399456654644e-33, '11': 1.0}
dense_angle_encode(qubit, data)

由于一个qubit不仅可以加载角度信息,还可以加载相位信息,因此,我们完全可以将一个长度为N的经典数据编码至 \(\lceil N \rceil\) 个量子比特上。

\[\begin{aligned} |\boldsymbol{x}\rangle=\bigotimes_{i=1}^{\lceil N / 2\rceil} \cos \left(\pi x_{2 i-1}\right)|0\rangle+e^{2 \pi i x_{2 i}} \sin \left(\pi x_{2 i-1}\right)|1\rangle \end{aligned}\]

其中,将两个数据分别编码至量子特的旋转角度 \(\cos \left(\pi x_{2 i-1}\right)|0\rangle\) 与相位信息中 \(e^{2 \pi i x_{2 i}} \sin \left(\pi x_{2 i-1}\right)|1\rangle\)

参数:
  • qubit (QVec) -- 编码比特列表。

  • data (List[float]) -- 编码数据。

返回:

None

返回类型:

None

可以发现,在经典角度编码中将经典数据向量 \(x\)\(y\) 轴旋转了 \(\pi\)。由于密集角度编码会将一半信息编码至量子态的相位信息中。那么,我们可以调用 pyqpandaqvm.directly_run 接口,获取系统的量子态信息,

from pyqpanda import *
import numpy as np

if __name__=="__main__":

    #构建全振幅虚拟机
    qvm = CPUQVM()
    qvm.init_qvm()
    x = [np.pi,np.pi]
    x = np.asarray(x)
    #实例化编码类Encode
    cir_encode = Encode()

    #申请量子比特
    qubits = qvm.qAlloc_many(1)
    cir_encode.dense_angle_encode(qubits,x)
    prog = QProg()
    prog << cir_encode.get_circuit()
    qvm.directly_run(prog)
    result = qvm.get_qstate()
    print(result)
    qvm.finalize()
[(6.123233995736766e-17+0j), (-1+1.2246467991473532e-16j)]

振幅编码即是将一个长度为 \(N\) 的数据向量 \(x\) 编码至数量为 \(\lceil log_{2}N \rceil\) 的量子比特的振幅上,具体公式如下:

\[\begin{aligned} \left|\psi\right\rangle=x_{0}|0\rangle+\cdots+x_{N-1}|N-1\rangle \end{aligned}\]

然而,可以发现由于处于纯态或混合态的量子系统的迹是为1的,所以我们需要将数据进行归一化处理,因此在接口入参时会进行校验。 同时,一个编码算法需要考虑的通常有三点,分别为编码线路的深度,宽度(qubit数量),以及CNOT门的数量。因此,对应以上三点,在pyqpanda中也提供了不同的编码方法。同时根据数据形式的不同也可分为密集数据编码和稀疏数据编码。

amplitude_encode(qubit, data)

Top-down[2]的编码方式,顾名思义,即是将数据向量先进行处理,得到对应的角度树,并从角度树的根节点开始,依次向下进行编码,如下图所示:

参数:
  • qubit (QVec) -- 编码比特列表。

  • data (List[float] 或 List[complex]) -- 编码数据。

返回:

None

返回类型:

None

_images/angle_tree.png _images/Top-down.png

这种编码方式具有 \(O(\lceil log_{2} N \rceil)\) 的线路宽度,以及 \(O(n)\) 的线路深度。

from pyqpanda import *
import numpy as np

if __name__=="__main__":
    machine=CPUQVM()
    machine.init_qvm()

    data = [0,1/np.sqrt(3),0,0,0,1/np.sqrt(3),1/np.sqrt(3),0]
    data = np.asarray(data)
    qubit = machine.qAlloc_many(3)
    cir_encode = Encode()
    cir_encode.amplitude_encode(qubit,data)
    prog = QProg()
    prog << cir_encode.get_circuit()
    encode_qubits = cir_encode.get_out_qubits()
    print(prog)
    result = machine.prob_run_dict(prog, encode_qubits)
    print(result)
    machine.finalize()
                                                               ┌────────────┐     ┌────────────┐     >
q_0:  |0>─────────────── ────────────── ─── ────────────── ─── RY(0.000000) ─── RY(3.141593) ─── >
                         ┌────────────┐     ┌────────────┐     └──────┬─────┘ ┌─┐ └──────┬─────┘ ┌─┐ >
q_1:  |0>─────────────── RY(1.570796) ─── RY(0.000000) ─── ───────■────── X ───────■────── X >
          ┌────────────┐ └──────┬─────┘ ┌─┐ └──────┬─────┘ ┌─┐               └─┘               ├─┤ >
q_2:  |0>─┤RY(1.910633) ───────■────── X ───────■────── X ───────■────── ─── ───────■────── X >
          └────────────┘                └─┘                └─┘                                   └─┘ >

         ┌────────────┐     ┌────────────┐
q_0:  |0>RY(0.000000) ─── RY(3.141593) ───
         └──────┬─────┘ ┌─┐ └──────┬─────┘ ┌─┐
q_1:  |0>───────■────── X ───────■────── X
                       └─┘               ├─┤
q_2:  |0>───────■────── ─── ───────■────── X
                                           └─┘

{'000': 1.2497998188848808e-33, '001': 0.33333333333333315, '010': 0.0, '011': 0.0, '100': 1.2497998188848817e-33, '101': 0.3333333333333334, '110': 0.3333333333333334, '111': 0.0}
dc_amplitude_encode(qubit, data)

与Top-down编码方式相反,Bottom-top[2]通过 \(O(n)\) 的宽度构建一个 \(O(\lceil log_{2} N \rceil)\) 深度的量子线路。 其中,角度树中最左子树( \(\alpha_{0}\) , \(\alpha_{1}\) , \(\alpha_{3}\) )对应的量子比特为输出比特,其余为辅助比特。构建形式如下图所示:

参数:
  • qubit (QVec) -- 编码比特列表。

  • data (List[float]) -- 编码数据。

返回:

None

返回类型:

None

_images/Bottom-top.png

其中,level1,与level2对应的量子逻辑门为受控SWAP门,其作用为交换辅助比特与输出比特量子态。

from pyqpanda import *
import numpy as np

if __name__=="__main__":
    machine = CPUQVM()
    machine.init_qvm()

    data = [0,1/np.sqrt(3),0,0,0,1/np.sqrt(3),1/np.sqrt(3),0]
    data = np.asarray(data)
    qubit = machine.qAlloc_many(7)
    cir_encode = Encode()
    cir_encode.dc_amplitude_encode(qubit,data)
    prog = QProg()
    prog << cir_encode.get_circuit()
    encode_qubits = cir_encode.get_out_qubits()
    print(prog)
    result = machine.prob_run_dict(prog, encode_qubits)
    print(result)
    machine.finalize()
          ┌────────────┐
q_0:  |0>─┤RY(1.910633) ─── ■─ ■─
          ├────────────┤       
q_1:  |0>─┤RY(0.000000) ■── X ┼─
          ├────────────┤      
q_2:  |0>─┤RY(1.570796) ┼■─ X ┼─
          ├────────────┤ ││     
q_3:  |0>─┤RY(3.141593) X┼─ ── X
          ├────────────┤ ││     
q_4:  |0>─┤RY(0.000000) X┼─ ── ┼─
          ├────────────┤       
q_5:  |0>─┤RY(3.141593) X ── X
          ├────────────┤  
q_6:  |0>─┤RY(0.000000) X ── ──
          └────────────┘


{'000': 1.2497998188848807e-33, '001': 0.33333333333333315, '010': 0.0, '011': 0.0, '100': 1.2497998188848817e-33, '101': 0.3333333333333334, '110': 0.3333333333333334, '111': 0.0}
bid_amplitude_encode(qubit, data, spilt)

双向振幅编码[2]则是综合了Top-down和Bottom-top两种编码方式,即可通过参数 \(split\) 控制决定其线路深度与宽度。 其线路宽度为 \(O_{w}\left(2^{split}+\log _{2}^{2}(N)-split^{2}\right)\) ,线路深度为 \(O_{d}\left((split+1) \frac{N}{2^{split}}\right)\) ,而在我们pyqpanda中的接口默认为 \(n/2\)。 从 \(O_{w}\)\(O_{d}\) 的公式可以看出当split为1时,则为Bottom-top振幅编码,当spilt为n时则为Top-down振幅编码。

参数:
  • qubit (QVec) -- 编码比特列表。

  • data (List[float]) -- 编码数据。

  • spilt (int) -- 量子线路深度与宽度调节因子,其宽度表达式为 \(O_{w}\left(2^{split}+\log _{2}^{2}(N)-split^{2}\right)\) ,深度表达式为 \(O_{d}\left((split+1) \frac{N}{2^{split}}\right)\),默认值为 \(N/2\)

返回:

None

返回类型:

None

Split状态树 Split为 ::math:`n/2` 线路
from pyqpanda import *
import numpy as np

if __name__=="__main__":
    machine=CPUQVM()
    machine.init_qvm()

    data = [0,1/np.sqrt(3),0,0,0,1/np.sqrt(3),1/np.sqrt(3),0]
    qubit = machine.qAlloc_many(5)
    data = np.asarray(data)
    cir_encode = Encode()
    cir_encode.bid_amplitude_encode(qubit,data)
    prog = QProg()
    prog << cir_encode.get_circuit()
    encode_qubits = cir_encode.get_out_qubits()
    print(prog)
    result = machine.prob_run_dict(prog, encode_qubits)
    print(result)
    machine.finalize()
          ┌────────────┐
q_0:  |0>─┤RY(1.910633) ────────────── ─── ────────────── ─── ■─ ■─
          ├────────────┤                ┌─┐                ┌─┐   
q_1:  |0>─┤RY(0.000000) ───────■────── X ───────■────── X X ┼─
          └────────────┘ ┌──────┴─────┐ └─┘ ┌──────┴─────┐ └─┘   
q_2:  |0>─────────────── RY(0.000000) ─── RY(3.141593) ─── ┼─ X
          ┌────────────┐ └────────────┘ ┌─┐ └────────────┘ ┌─┐   
q_3:  |0>─┤RY(1.570796) ───────■────── X ───────■────── X X ┼─
          └────────────┘ ┌──────┴─────┐ └─┘ ┌──────┴─────┐ └─┘    
q_4:  |0>─────────────── RY(0.000000) ─── RY(3.141593) ─── ── X
                         └────────────┘     └────────────┘


{'000': 1.2497998188848807e-33, '001': 0.33333333333333315, '010': 0.0, '011': 0.0, '100': 1.2497998188848813e-33, '101': 0.3333333333333334, '110': 0.3333333333333334, '111': 0.0}
schmidt_encode(qubit, data, cutoff)

如Top-down振幅编码所示,使用 \(\lceil log_{2} N \rceil\) 个量子比特编码长度为 :\(N\) 的经典数据大约需要 \(2^{2n}\) 个受控旋转门,这极大的降低了量子线路的 保真度,然而基于schmidt分解振幅编码[3]可以有效降低线路中的受控旋转门数量。首先,一个纯态 \(|\psi\rangle\) 可以被表示为如下形式:

\[\begin{aligned} |\psi\rangle=\sum_{i=1}^{k} \lambda_{i}\left|\alpha_{i}\right\rangle \otimes\left|\beta_{i}\right\rangle \end{aligned}\]

进一步,可以表示为:

\[\begin{aligned} |\psi\rangle=\sum_{i=1}^{m} \sum_{j=1}^{n} C_{i j}\left|e_{i}\right\rangle \otimes\left|f_{j}\right\rangle \end{aligned}\]

其中,\(\left|e_{i}\right\rangle \in \mathbb{C}^{m},\left|f_{j}\right\rangle \in \mathbb{C}^{n}\)。而 \(C\) 可以进行奇异值分解(svd) \(C=U \Sigma V^{\dagger}\), 通过以上公式,我们可以得出 \(\sigma_{i i}=\lambda_{i}\)\(\left|\alpha_{i}\right\rangle=U\left|e_{i}\right\rangle\)\(\left|\beta_{i}\right\rangle=V^{\dagger}\left|f_{i}\right\rangle\), 其中,\(\sigma_{i i}\) 则是 \(C\) 的奇异值。线路图构建如下:

参数:
  • qubit (QVec) -- 编码比特列表。

  • data (List[float]) -- 编码数据。

  • cutoff (double) -- 表示奇异值向量的截断系数,范围为[0,1),0表示不截断。

返回:

None

返回类型:

None

from pyqpanda import *
import numpy as np

if __name__=="__main__":
    machine=CPUQVM()
    machine.init_qvm()

    data = [0,1/np.sqrt(3),0,0,0,1/np.sqrt(3),1/np.sqrt(3),0]
    data = np.asarray(data)
    qubit = machine.qAlloc_many(3)
    cir_encode = Encode()
    cir_encode.schmidt_encode(qubit,data,0)
    prog = QProg()
    prog << cir_encode.get_circuit()
    encode_qubits = cir_encode.get_out_qubits()
    print(prog)
    result = machine.prob_run_dict(prog, encode_qubits)
    print(result)
    machine.finalize()
                         ┌────┐              ┌────────────┐  ┌─────────────┐ ┌─────────────┐ ┌────────────┐ >
q_0:  |0>─────────────── CNOT├───────────── RZ(3.141593)├─ RY(-2.588018) RZ(-3.141593) RX(1.570796) >
          ┌────────────┐ └──┬┬┴────────────┐ ├────────────┤  └─────────────┘ └─────────────┘ └────────────┘ >
q_1:  |0>─┤RZ(4.712389) ───┼┤RY(-1.570796) RZ(1.570796)├─ ─────────────── ─────────────── ────────────── >
          ├────────────┤    │└─────────────┘ ├────────────┴┐ ┌─────────────┐                                >
q_2:  |0>─┤RY(0.729728) ───■─────────────── RY(-2.034444) RZ(-3.141593) ─────────────── ────────────── >
          └────────────┘                     └─────────────┘ └─────────────┘                                >

                ┌─────────────┐        ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌────────────┐ ┌─────────────┐
q_0:  |0>───■── RX(-1.570796) ───■── RX(-1.570796) RY(-1.570796) RZ(-1.570796) U1(4.712389) RZ(-4.712389)
         ┌──┴─┐ ├─────────────┤ ┌──┴─┐ ├─────────────┤ └─────────────┘ └─────────────┘ └────────────┘ └─────────────┘
q_1:  |0>CNOT RY(-1.017222) CNOT RY(-3.141593) ─────────────── ─────────────── ────────────── ───────────────
         └────┘ └─────────────┘ └────┘ └─────────────┘
q_2:  |0>────── ─────────────── ────── ─────────────── ─────────────── ─────────────── ────────────── ───────────────



{'000': 1.4442161374080831e-64, '001': 0.3333333333333333, '010': 3.8518598887744744e-32, '011': 1.2497998188848808e-33, '100': 1.2497998188848825e-33, '101': 0.3333333333333337, '110': 0.3333333333333337, '111': 1.2497998188848825e-33}
approx_mps(qubit, data, layers=3, sweeps=100, double2float=False)

MPS近似编码[4]是一种利用矩阵乘积态的低秩表达近似分布制备算法,可以通过一种较少的CNOT的门完成对分布的表达, 并且这种表达是一种近邻接形式,因此可以直接作用于芯片,且双门个数的减少,也有利于增加分布制备的成功率,量子线路图如下所示。

参数:
  • qubit (QVec) -- 编码比特列表。

  • data (List[float] 或 List[complex]) -- 编码数据。

  • layers (int) -- 表示MPS解纠缠的所需的近似层数,一般来说,层数越多,近似度越高, 默认值为3。

  • sweep (int) -- 表示通过环境张量优化迭代次数,默认值为100。

  • double2float (bool) -- 表示将数据向量的类型从双精度变为单精度。

返回:

None

返回类型:

None

_images/MPS_circuit.png

可以发现该函数支持多种类型数据制备(float,double,complex),其中layers指的是使用矩阵乘积态近似的层数,sweeps是指通过环境张量优化的迭代次数,double2float则是表示是否需要将双精度数据转为单精度类型处理,从而加速生成线路。环境张量的数学表达如下:

\[\begin{aligned} \hat{\mathcal{F}}_m=\operatorname{Tr}_{\bar{U}_m}\left[\prod_{i=M}^{m+1} U_i\left|\psi_{\chi_{\max }}\right\rangle\left\langle 0^{\otimes N}\right| \prod_{j=1}^{m-1} U_j^{\dagger}\right] \end{aligned}\]

其中, \(\operatorname{Tr}_{\bar{U}_m}\) 指的是不与 \(U_m\) 相互作用的量子比特索引上的偏迹,环境张量 \(\hat{\mathcal{F}}_m\) 则被表示为一个4x4的矩阵,在实际中可以通过从量子线路中移除 \(U_m\) 并收缩剩余的张量来计算(见下图),并同时始终保持MPS结构。 最后,为了适配芯片的拓扑结构,该制备算法的 \(chi\) 均为2。

_images/MPS_tensor.png

下面,我们以W-state作为示例,展示MPS近似编码的神奇,即在无论多少比特的W-state,均可在一层解纠缠下完成准确编码。因此,针对纠缠度较低的数据,如正太分布数据,可在一个较低深度下近似表达。

from pyqpanda import *
import numpy as np

if __name__=="__main__":
    machine = CPUQVM()
    machine.init_qvm()

    n_qubits = 5
    w_state = [0]*2**n_qubits
    for i in range(n_qubits):
        w_state[1<<i] = 1/np.sqrt(n_qubits)
    w_state = np.asarray(w_state)
    qubit = machine.qAlloc_many(n_qubits)
    cir_encode = Encode()
    cir_encode.approx_mps(qubit,data = w_state,layers=1)
    prog = QProg()
    prog << cir_encode.get_circuit()
    encode_qubits = cir_encode.get_out_qubits()
    print(prog)
    result = machine.prob_run_dict(prog, encode_qubits)
    print(result)
    machine.finalize()
          ┌─────────────┐ ┌─────────────┐ ┌────────────┐ ┌────────────┐        ┌─────────────┐        >
q_0:  |0>─┤RZ(-1.570796) RY(-1.570796) RZ(4.712389) RX(1.570796) ───■── RX(-1.570796) ───■── >
          ├─────────────┤ ├────────────┬┘ └────────────┘ └────────────┘ ┌──┴─┐ ├─────────────┤ ┌──┴─┐ >
q_1:  |0>─┤RY(-0.463648) RZ(3.141593)├─ ────────────── ────────────── CNOT RY(-1.107149) CNOT >
          ├─────────────┤ ├────────────┴┐                               └────┘ └─────────────┘ └────┘ >
q_2:  |0>─┤RZ(-1.178097) RZ(-1.178097) ────────────── ────────────── ────── ─────────────── ────── >
          ├────────────┬┘ ├─────────────┤                                                             >
q_3:  |0>─┤RZ(5.497787)├─ RY(-1.570796) ────────────── ────────────── ────── ─────────────── ────── >
          ├────────────┴┐ ├─────────────┤                                                             >
q_4:  |0>─┤RZ(-1.963495) RZ(-1.963495) ────────────── ────────────── ────── ─────────────── ────── >
          └─────────────┘ └─────────────┘                                                             >

         ┌─────────────┐ ┌────────────┐  ┌─────────────┐ ┌────────────┐                                       >
q_0:  |0>RX(-1.570796) RZ(3.141593)├─ U1(-4.712389) RZ(4.712389) ────────────── ────── ─────────────── >
         ├─────────────┤ ├────────────┴┐ ├────────────┬┘ ├────────────┤ ┌────────────┐        ┌─────────────┐ >
q_1:  |0>RY(-1.570796) RZ(-4.712389) RZ(2.748894)├─ RZ(2.748894) RX(1.570796) ───■── RX(-1.047198) >
         └─────────────┘ └─────────────┘ └────────────┘  └────────────┘ └────────────┘ ┌──┴─┐ ├─────────────┤ >
q_2:  |0>─────────────── ─────────────── ─────────────── ────────────── ────────────── CNOT RY(-1.047198) >
                                                                                       └────┘ └─────────────┘ >
q_3:  |0>─────────────── ─────────────── ─────────────── ────────────── ────────────── ────── ─────────────── >
                                                                                                              >
q_4:  |0>─────────────── ─────────────── ─────────────── ────────────── ────────────── ────── ─────────────── >
                                                                                                              >

                                                                                                      >
q_0:  |0>────── ─────────────── ─────────────── ─────────────── ─────────────── ────── ────────────── >
                ┌─────────────┐ ┌─────────────┐ ┌─────────────┐                                       >
q_1:  |0>───■── RX(-1.570796) RZ(-2.748894) RZ(-2.748894) ─────────────── ────── ────────────── >
         ┌──┴─┐ ├────────────┬┘ ├────────────┬┘ ├────────────┬┘ ┌─────────────┐                       >
q_2:  |0>CNOT RZ(1.178097)├─ RZ(1.178097)├─ RZ(3.926991)├─ RY(-1.570796) ───■── ────────────── >
         └────┘ └────────────┘  └────────────┘  └────────────┘  └─────────────┘ ┌──┴─┐ ┌────────────┐ >
q_3:  |0>────── ─────────────── ─────────────── ─────────────── ─────────────── CNOT RZ(0.615480) >
                                                                                └────┘ └────────────┘ >
q_4:  |0>────── ─────────────── ─────────────── ─────────────── ─────────────── ────── ────────────── >
                                                                                                      >

                                                                                                     >
q_0:  |0>────────────── ────── ────────────── ────── ─────────────── ─────────────── ─────────────── >
                                                                                                     >
q_1:  |0>────────────── ────── ────────────── ────── ─────────────── ─────────────── ─────────────── >
                        ┌────┐ ┌────────────┐        ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ >
q_2:  |0>────────────── CNOT RX(0.000000) ───■── RX(-1.570796) RZ(-3.141593) RY(-1.570796) >
         ┌────────────┐ └──┬─┘ ├────────────┤ ┌──┴─┐ ├────────────┬┘ ├─────────────┤ ├─────────────┤ >
q_3:  |0>RX(1.570796) ───■── RY(0.615480) CNOT RZ(3.141593)├─ RY(-1.570796) RZ(-0.785398) >
         └────────────┘        └────────────┘ └────┘ └────────────┘  └─────────────┘ └─────────────┘ >
q_4:  |0>────────────── ────── ────────────── ────── ─────────────── ─────────────── ─────────────── >
                                                                                                     >


q_0:  |0>─────────────── ─────────────── ────────────── ────── ─────────────── ────── ─────────────── ─────────────── ──────────────

q_1:  |0>─────────────── ─────────────── ────────────── ────── ─────────────── ────── ─────────────── ─────────────── ──────────────
         ┌─────────────┐ ┌─────────────┐ ┌────────────┐
q_2:  |0>RZ(-2.356194) U1(-6.283185) RZ(6.283185) ────── ─────────────── ────── ─────────────── ─────────────── ──────────────
         ├─────────────┤ ├─────────────┤ ├────────────┤        ┌─────────────┐        ┌─────────────┐ ┌────────────┐  ┌────────────┐
q_3:  |0>RZ(-2.748894) RZ(-2.748894) RX(1.570796) ───■── RX(-0.785398) ───■── RX(-1.570796) RZ(1.178097)├─ RZ(1.178097)
         └─────────────┘ └─────────────┘ └────────────┘ ┌──┴─┐ ├─────────────┤ ┌──┴─┐ ├─────────────┤ ├────────────┴┐ └────────────┘
q_4:  |0>─────────────── ─────────────── ────────────── CNOT RY(-0.785398) CNOT RZ(-2.748894) RZ(-2.748894) ──────────────
                                                        └────┘ └─────────────┘ └────┘ └─────────────┘ └─────────────┘


{'00000': 4.468157470978386e-32, '00001': 0.20000000000000048, '00010': 0.2000000000000004, '00011': 0.0, '00100': 0.20000000000000048, '00101': 7.4987989133093034e-34, '00110': 7.498798913309305e-34, '00111': 0.0, '01000': 0.20000000000000023, '01001': 1.4102295515520025e-35, '01010': 1.4102295515519843e-35, '01011': 0.0, '01100': 4.818833738106373e-33, '01101': 9.629649721936199e-35, '01110': 1.1555579666323412e-33, '01111': 0.0, '10000': 0.20000000000000023, '10001': 1.410229551551963e-35, '10010': 1.4102295515519827e-35, '10011': 0.0, '10100': 4.818833738106368e-33, '10101': 9.629649721936196e-35, '10110': 1.1555579666323415e-33, '10111': 0.0, '11000': 0.0, '11001': 3.851859888774471e-34, '11010': 0.0, '11011': 0.0, '11100': 3.851859888774471e-34, '11101': 5.934729841099873e-67, '11110': 0.0, '11111': 0.0}
ds_quantum_state_preparation(qubit, data)

双稀疏量子态编码[5]通过利用 \(n\) 个辅助比特辅助构建线路。我们以编码 \(|001\rangle\) 为例,如下图所示:

参数:
  • qubit (QVec) -- 编码比特列表。

  • data (List[float] 或 List[complex]) -- 编码数据。

返回:

None

返回类型:

None

_images/double_sparse.png

其中,\(|\mu\rangle\) 为辅助寄存器用以作用旋转门,并受输出寄存器 \(|m\rangle\) 控制,而当所需编码的字符下标的1的个数较多时,则需要作用多控门,而为了减少消除线路中多控门的数量,我们 通过增加一部分辅助寄存器,并利用Toffoli门进行分解,其原理如下图所示:

_images/double_sparse_decompostion.png
from pyqpanda import *
import numpy as np

if __name__=="__main__":
    machine = CPUQVM()
    machine.init_qvm()
    data = [0,1/np.sqrt(3),0,0,0,1/np.sqrt(3),1/np.sqrt(3),0]
    data = np.asarray(data)
    qubit = machine.qAlloc_many(6)
    cir_encode = Encode()
    cir_encode.ds_quantum_state_preparation(qubit,data)
    prog = QProg()
    prog << cir_encode.get_circuit()
    encode_qubits = cir_encode.get_out_qubits()
    print(prog)
    result = machine.prob_run_dict(prog, encode_qubits)
    print(result)
    machine.finalize()
          ┌─┐        ┌───────────────────────────────┐                          ┌───────────────────────────────┐ >
q_0:  |0>─┤X ───■── U3(-1.230959,0.000000,0.000000) ───■── ───■── ───■── ─── U3(-1.570796,0.000000,0.000000) >
          └─┘       └───────────────┬───────────────┘                   ┌─┐ └───────────────┬───────────────┘ >
q_2:  |0>──── ───┼── ────────────────┼──────────────── ───┼── ───┼── ───┼── X ────────────────■──────────────── >
              ┌──┴─┐                                  ┌──┴─┐ ┌──┴─┐       └┬┘                                   >
q_3:  |0>──── CNOT ────────────────■──────────────── CNOT CNOT ───┼── ─■─ ───────────────────────────────── >
              └────┘                                   └────┘ └────┘                                            >
q_4:  |0>──── ────── ───────────────────────────────── ────── ────── ───┼── ─┼─ ───────────────────────────────── >
                                                                     ┌──┴─┐                                      >
q_5:  |0>──── ────── ───────────────────────────────── ────── ────── CNOT ─■─ ───────────────────────────────── >
                                                                     └────┘                                       >

                                             ┌───────────────────────────────┐
q_0:  |0>─── ───■── ───■── ───■── ───■── ─── U3(-3.141593,0.000000,0.000000) ───
         ┌─┐                         ┌─┐ └───────────────┬───────────────┘ ┌─┐
q_2:  |0>X ───┼── ───┼── ───┼── ───┼── X ────────────────■──────────────── X
         └┬┘ ┌──┴─┐                   └┬┘                                   └┬┘
q_3:  |0>─■─ CNOT ───┼── ───┼── ───┼── ─┼─ ───────────────────────────────── ─┼─
            └────┘       ┌──┴─┐                                             
q_4:  |0>─┼─ ────── ───┼── CNOT ───┼── ─■─ ───────────────────────────────── ─■─
                   ┌──┴─┐ └────┘ ┌──┴─┐                                       
q_5:  |0>─■─ ────── CNOT ────── CNOT ─■─ ───────────────────────────────── ─■─
                    └────┘        └────┘


{'000': 0.0, '001': 0.3333333333333333, '010': 0.0, '011': 0.0, '100': 0.0, '101': 0.3333333333333334, '110': 0.33333333333333315, '111': 0.0}
sparse_isometry(qubit, data)

sparse_isometry编码[6]不同于双稀疏量子态编码需要辅助比特去构建线路。 sparse_isometry编码首先通过将长度为 \(N\) 稀疏数据向量中的非0元素 \(x\) 统一编码至前 \(\lceil log_2len(x) \rceil\) 个量子比特上,后通过受控X门对其进行受控转化。其线路构建如下图所示:

参数:
  • qubit (QVec) -- 编码比特列表。

  • data (List[float] 或 List[complex]) -- 编码数据。

返回:

None

返回类型:

None

_images/sparse_isometry.png

其中,\(n+m=\lceil log_2N \rceil\) \(|\alpha\rangle\)\(\lceil log_2len(x) \rceil\) 个非0元素的编码encode模块, 而 \(|\beta\rangle\) 则为剩余qubit。 其中transform模块则是转化模块。

from pyqpanda import *
import numpy as np

if __name__=="__main__":
    machine = CPUQVM()
    machine.init_qvm()
    data = [0,1/np.sqrt(3),0,0,0,1/np.sqrt(3),1/np.sqrt(3),0]
    data = np.asarray(data)
    qubit = machine.qAlloc_many(3)
    cir_encode = Encode()
    cir_encode.sparse_isometry(qubit,data)
    prog = QProg()
    prog << cir_encode.get_circuit()
    encode_qubits = cir_encode.get_out_qubits()
    print(prog)
    result = machine.prob_run_dict(prog, encode_qubits)
    print(result)
    machine.finalize()
                         ┌────────────┐     ┌────────────┐ ┌─┐     ┌─┐ ┌─┐ ┌─┐     ┌─┐ ┌─┐
q_0:  |0>─────────────── RY(0.000000) ─── RY(1.570796) X ─■─ X X X ─■─ X X
          ┌────────────┐ └──────┬─────┘ ┌─┐ └──────┬─────┘ ├─┤    ├─┤ └┬┘ └─┘    ├─┤ └┬┘
q_1:  |0>─┤RY(1.230959) ───────■────── X ───────■────── X ─■─ X ─┼─ ─── ─■─ X ─┼─
          └────────────┘                └─┘                └─┘ ┌┴┐ └─┘        ┌┴┐ └─┘  
q_2:  |0>─────────────── ────────────── ─── ────────────── ─── X ─── ─■─ ─── X ─── ─■─
                                                               └─┘             └─┘


{'000': 0.0, '001': 0.3333333333333334, '010': 0.0, '011': 0.0, '100': 0.0, '101': 0.3333333333333333, '110': 0.3333333333333333, '111': 0.0}
efficient_sparse(qubit, data)

多项式稀疏量子态编码[7]是一种稀疏数据向量中的非0元素个数与qubit个数成线性关系的稀疏数据编码方式。其线路编码深度为 \(O\left(|S|^{2} \log (|S|) n\right)\) 。 其中,\(|S|\) 为非0元素个数,\(n\) 为所需qubit个数,即为 \(\lceil log_2N \rceil\) , \(N\) 为稀疏数据长度。下面以编码 \(|x\rangle=1/\sqrt{3}(|001\rangle+|100\rangle+|111\rangle)\) 为例,其线路图构建如下:

参数:
  • qubit (QVec) -- 编码比特列表。

  • data (List[float] 或 List[complex]) -- 编码数据。

返回:

None

返回类型:

None

_images/efficient_encode.png

其中,F门是将 \(|0\rangle\) 映射到 \(1/\sqrt{3}|0\rangle+1/\sqrt{3}|1\rangle\) ,而G门则是将 \(|0\rangle\) 映射到 \(1/\sqrt{3}|0\rangle+2/\sqrt{3}|1\rangle\)

from pyqpanda import *
import numpy as np

if __name__=="__main__":
    machine = CPUQVM()
    machine.init_qvm()
    data = [0,1/np.sqrt(3),0,0,0,1/np.sqrt(3),1/np.sqrt(3),0]
    data = np.asarray(data)
    qubit = machine.qAlloc_many(3)
    cir_encode = Encode()
    cir_encode.efficient_sparse(qubit,data)
    prog = QProg()
    prog << cir_encode.get_circuit()
    encode_qubits = cir_encode.get_out_qubits()
    print(prog)
    result = machine.prob_run_dict(prog, encode_qubits)
    print(result)
    machine.finalize()
          ┌─┐                                      ┌────┐                                             >
q_0:  |0>─┤X ──────────────────────────────────── CNOT ────── ──────────────────────────────────── >
          └─┘                                      └──┬─┘ ┌────┐                                      >
q_1:  |0>──── ──────────────────────────────────── ───┼── CNOT ──────────────────■───────────────── >
          ┌─┐ ┌──────────────────────────────────┐       └──┬─┘ ┌─────────────────┴────────────────┐ >
q_2:  |0>─┤X U3(1.230959,0.000000,0.000000).dag ───■── ───■── U3(1.570796,0.000000,0.000000).dag >
          └─┘ └──────────────────────────────────┘               └──────────────────────────────────┘ >

         ┌────┐
q_0:  |0>CNOT ────── ───
         └──┬─┘ ┌────┐
q_1:  |0>───┼── CNOT ───
               └──┬─┘ ┌─┐
q_2:  |0>───■── ───■── X
                       └─┘


{'000': 0.0, '001': 0.3333333333333333, '010': 0.0, '011': 0.0, '100': 0.0, '101': 0.3333333333333333, '110': 0.3333333333333334, '111': 0.0}
iqp_encode(qubit, data, control_vector=None, inverse=false, repeats=1)

IQP编码[8] iqp_encode(qubit, data, control_vector = None, inverse=false, repeats = 1) 是一种应用于量子机器学习的编码方法。将一个经典数据x编码到

\[\begin{aligned} |\mathbf{x}\rangle=\left(\mathrm{U}_{\mathrm{Z}}(\mathbf{x}) \mathrm{H}^{\otimes n}\right)^{\boldsymbol{r}}\left|0^{n}\right\rangle \end{aligned}\]

其中, \(r\) 表示量子线路的深度,也就是 \(\mathrm{U}_{\mathrm{Z}}(\mathbf{x}) \mathrm{H}^{\otimes n}\) 重复的次数。\(\mathrm{H}^{\otimes n}\) 是一层作用在所有量子比特上的Hadamard门。其中, \(\mathrm{U}_\mathrm{Z}\)

\[\begin{aligned} \mathrm{U}_\mathrm{Z}(\mathbf{x})=\prod_{[i, j] \in S} R_{Z_{i} Z_{j}}\left(x_{i} x_{j}\right) \bigotimes_{k=1}^{n} R_{z}\left(x_{k}\right) \end{aligned}\]

这里的 \(S\) 是一个集合,对于这个集合中的每一对量子比特,我们都需要对它们作用 \(R_{ZZ}\) 门。\(R_{ZZ}\) 门的构建形式如下:

参数:
  • qubit (QVec) -- 编码比特列表。

  • data (List[float]) -- 编码数据。

  • control_vector (List[tuple]) -- 控制序列,默认为空,则表示按序控制。

  • inverse (int) -- 是否翻转线路,默认为False。

  • inverse -- 表示重复模块次数,默认为1。

返回:

None

返回类型:

None

_images/RZZ.png

下面我们以编码 \(data=[-1.3, 1.8, 2.6, -0.15]\) 为例介绍:

from pyqpanda import *
import numpy as np

if __name__=="__main__":
    machine=CPUQVM()
    machine.init_qvm()

    data = [-1.3, 1.8, 2.6, -0.15]
    data = np.asarray(data)
    qubit = machine.qAlloc_many(4)
    cir_encode = Encode()
    cir_encode.iqp_encode(qubit,data)
    prog = QProg()
    prog << cir_encode.get_circuit()
    print(prog)
    encode_qubits = cir_encode.get_out_qubits()
    machine.directly_run(prog)
    result = machine.get_qstate()
    print(result)
    machine.finalize()
          ┌─┐ ┌─────────────┐
q_0:  |0>─┤H RZ(-1.300000) ───■── ─────────────── ───■── ────── ────────────── ────── ────── ─────────────── ──────
          ├─┤ ├────────────┬┘ ┌──┴─┐ ┌─────────────┐ ┌──┴─┐
q_1:  |0>─┤H RZ(1.800000)├─ CNOT RZ(-2.340000) CNOT ───■── ────────────── ───■── ────── ─────────────── ──────
          ├─┤ ├────────────┤  └────┘ └─────────────┘ └────┘ ┌──┴─┐ ┌────────────┐ ┌──┴─┐
q_2:  |0>─┤H RZ(2.600000)├─ ────── ─────────────── ────── CNOT RZ(4.680000) CNOT ───■── ─────────────── ───■──
          ├─┤ ├────────────┴┐                               └────┘ └────────────┘ └────┘ ┌──┴─┐ ┌─────────────┐ ┌──┴─┐
q_3:  |0>─┤H RZ(-0.150000) ────── ─────────────── ────── ────── ────────────── ────── CNOT RZ(-0.390000) CNOT
          └─┘ └─────────────┘                                                            └────┘ └─────────────┘ └────┘


[(-0.1925578135118269-0.15944117553362588j), (0.24534942018697528+0.047996479182488616j), (-0.02973039232415307+0.24822591277352968j), (-0.22912120333719244+0.10001736939810474j), (-0.06725827577934981-0.2407827326433292j), (0.17417667733679137+0.17933902272488078j), (0.1777283845030693-0.17581985480010265j), (0.2415974945336283+0.06427013797303885j), (-0.24713295520684903-0.037753178021585905j), (0.23511504508229614-0.08497597057962829j), (0.10212186022103938+0.22819098506513033j), (-0.14509671578880565+0.20358522310644894j), (-0.008095829439931083-0.249868880706821j), (0.1265550643081946+0.2156010568108347j), (0.21442717034095604-0.12853399791327838j), (0.21939564047259316+0.11985638465105079j)]
[1] Schuld, Maria. "Quantum machine learning models are kernel methods."[J] arXiv:2101.11020 (2021).
[2] Araujo I F, Park D K, Ludermir T B, et al. "Configurable sublinear circuits for quantum state preparation."[J]. arXiv preprint arXiv:2108.10182, 2021.
[3] Ghosh K. "Encoding classical data into a quantum computer"[J]. arXiv preprint arXiv:2107.09155, 2021.
[4] Rudolph M S, Chen J, Miller J, et al. Decomposition of matrix product states into shallow quantum circuits[J]. arXiv preprint arXiv:2209.00595, 2022.
[5] de Veras T M L, da Silva L D, da Silva A J. "Double sparse quantum state preparation"[J]. arXiv preprint arXiv:2108.13527, 2021.
[6] Malvetti E, Iten R, Colbeck R. "Quantum circuits for sparse isometries"[J]. Quantum, 2021, 5: 412.
[7] N. Gleinig and T. Hoefler, "An Efficient Algorithm for Sparse Quantum State Preparation," 2021 58th ACM/IEEE Design Automation Conference (DAC), 2021, pp. 433-438, doi: 10.1109/DAC18074.2021.9586240.
[8] Havlíček, Vojtěch, et al. "Supervised learning with quantum-enhanced feature spaces." Nature 567.7747 (2019): 209-212.

pyqpanda.pyQPanda

Module Contents

Classes

AbstractOptimizer

quantum AbstractOptimizer class

AdaGradOptimizer

variational quantum AdaGradOptimizer

AdamOptimizer

variational quantum AdamOptimizer

Ansatz

quantum ansatz class

AnsatzGate

ansatz gate struct

AnsatzGateType

Quantum ansatz gate type

BackendType

Quantum machine backend type

CBit

quantum classical bit

CPUQVM

quantum machine cpu

CPUSingleThreadQVM

quantum machine class for cpu single thread

ChipID

origin quantum real chip type

ClassicalCondition

Classical condition class Proxy class of cexpr class

ClassicalProg

quantum ClassicalProg

CommProtocolConfig

ComplexVertexSplitMethod

quantum complex vertex split method

DAGNodeType

Quantum dag node type

DecompositionMode

Quantum matrix decomposition mode

DensityMatrixSimulator

simulator for density matrix

DoubleGateTransferType

Quantum double gate transfer type

Encode

quantum amplitude encode

ErrorCode

pliot error code

Fusion

quantum fusion operation

GateType

quantum gate type

HHLAlg

quantum hhl algorithm class

LATEX_GATE_TYPE

Quantum latex gate type

LatexMatrix

Generate quantum circuits latex src code can be compiled on latex package 'qcircuit'

MPSQVM

quantum matrix product state machine class

MomentumOptimizer

variational quantum MomentumOptimizer

NodeInfo

Detailed information of a QProg node

NodeIter

quantum node iter

NodeType

quantum node type

Noise

Quantum machine for noise simulation

NoiseModel

noise model type

NoiseQVM

quantum machine class for simulate noise prog

Optimizer

variational quantum Optimizer class

OptimizerFactory

quantum OptimizerFactory class

OptimizerMode

variational quantum OptimizerMode

OptimizerType

quantum OptimizerType

OriginCMem

origin quantum cmem

OriginCollection

A relatively free data collection class for saving data

OriginQubitPool

quantum qubit pool

PartialAmpQVM

quantum partial amplitude machine class

PhysicalQubit

Physical Qubit abstract class

PilotNoiseParams

pliot noise simulate params

ProgCount

QCircuit

quantum circuit node

QCircuitOPtimizerMode

Quantum circuit optimize mode

QCloudService

origin quantum cloud machine

QCloudTaskConfig

QError

Quantum QError Type

QGate

quantum gate node

QITE

quantum imaginary time evolution

QIfProg

quantum if prog node

QMachineType

Quantum machine type

QMeasure

quantum measure node

QOperator

quantum operator class

QOptimizationResult

quantum QOptimizationResult class

QPilotMachine

pliot machine

QPilotOSService

origin quantum pilot OS Machine

QProg

Quantum program,can construct quantum circuit,data struct is linked list

QProgDAG

quantum prog dag class

QProgDAGEdge

quantum prog dag edge

QProgDAGVertex

quantum prog dag vertex node

QReset

quantum reset node

QResult

QResult abstract class, this class contains the result of the quantum measurement

QVec

Qubit vector basic class

QWhileProg

quantum while node

QuantumMachine

quantum machine base class

QuantumStateTomography

quantum state tomography class

Qubit

Qubit abstract class

RMSPropOptimizer

variational quantum RMSPropOptimizer

SingleAmpQVM

quantum single amplitude machine class

SingleGateTransferType

Quantum single gate transfer type

SparseQVM

quantum sparse machine class

Stabilizer

simulator for basic clifford simulator

UpdateMode

quantum imaginary time evolution update mode

VanillaGradientDescentOptimizer

variational quantum VanillaGradientDescentOptimizer

VariationalQuantumCircuit

variational quantum CIRCUIT class

VariationalQuantumGate

variational quantum gate base class

VariationalQuantumGate_CNOT

variational quantum CNOT gate class

VariationalQuantumGate_CR

variational quantum CR gate class

VariationalQuantumGate_CRX

variational quantum CRX gate class

VariationalQuantumGate_CRY

variational quantum CRY gate class

VariationalQuantumGate_CRZ

variational quantum CRZ gate class

VariationalQuantumGate_CU

variational quantum CU gate class

VariationalQuantumGate_CZ

variational quantum CZ gate class

VariationalQuantumGate_H

variational quantum H gate class

VariationalQuantumGate_I

variational quantum I gate class

VariationalQuantumGate_RX

variational quantum RX gate class

VariationalQuantumGate_RY

variational quantum RY gate class

VariationalQuantumGate_RZ

variational quantum RZ gate class

VariationalQuantumGate_S

variational quantum S gate class

VariationalQuantumGate_SWAP

variational quantum SWAP gate class

VariationalQuantumGate_SqiSWAP

variational quantum SqiSWAP gate class

VariationalQuantumGate_T

variational quantum T gate class

VariationalQuantumGate_U1

variational quantum U1 gate class

VariationalQuantumGate_U2

variational quantum U2 gate class

VariationalQuantumGate_U3

variational quantum U3 gate class

VariationalQuantumGate_U4

variational quantum U4 gate class

VariationalQuantumGate_X

variational quantum X gate class

VariationalQuantumGate_X1

variational quantum X1 gate class

VariationalQuantumGate_Y

variational quantum Y gate class

VariationalQuantumGate_Y1

variational quantum Y1 gate class

VariationalQuantumGate_Z

variational quantum Z gate class

VariationalQuantumGate_Z1

variational quantum Z1 gate class

VariationalQuantumGate_iSWAP

variational quantum iSWAP gate class

em_method

origin quantum real chip error_mitigation type

expression

variational quantum expression class

hadamard_circuit

hadamard circuit class

real_chip_type

origin quantum real chip type enum

var

quantum variational class

Functions

BARRIER(…)

Create a BARRIER gate

CNOT(…)

Returns:

CP(…)

Returns:

CR(…)

Returns:

CU(…)

Create a CU gate

CZ(…)

Returns:

CreateEmptyCircuit(→ QCircuit)

Create an empty QCircuit Container

CreateEmptyQProg(→ QProg)

Create an empty QProg Container

CreateIfProg(…)

Create a classical quantum IfProg

CreateWhileProg(→ QWhileProg)

Create a WhileProg

Grover(→ Any)

Quantum grover circuit

Grover_search(…)

use Grover algorithm to search target data, return QProg and search_result

H(…)

Create a H gate

HHL_solve_linear_equations(→ List[complex])

Use HHL algorithm to solve the target linear systems of equations : Ax = b

I(…)

Create a I gate

MAJ(→ QCircuit)

Quantum adder MAJ module

MAJ2(→ QCircuit)

Quantum adder MAJ2 module

MS(…)

Returns:

Measure(…)

Create an measure node

OBMT_mapping(…)

OPT_BMT mapping

P(…)

Create a P gate

PMeasure(→ List[Tuple[int, float]])

Deprecated, use pmeasure instead

PMeasure_no_index(→ List[float])

Deprecated, use pmeasure_no_index instead

QAdd(→ QCircuit)

Quantum adder that supports signed operations, but ignore carry

QAdder(→ QCircuit)

Quantum adder with carry

QAdderIgnoreCarry(→ QCircuit)

Args:

QComplement(→ QCircuit)

Convert quantum state to binary complement representation

QDiv(→ QProg)

Quantum division

QDivWithAccuracy(→ QProg)

Args:

QDivider(→ QProg)

Quantum division, only supports positive division, and the highest position of a and b and c is sign bit

QDividerWithAccuracy(→ QProg)

Args:

QDouble(…)

Returns:

QFT(→ QCircuit)

Build QFT quantum circuit

QMul(→ QCircuit)

Quantum multiplication

QMultiplier(→ QCircuit)

Quantum multiplication, only supports positive multiplication

QOracle(→ QGate)

Generate QOracle Gate

QPE(→ QCircuit)

Quantum phase estimation

QSub(→ QCircuit)

Quantum subtraction

RX(…)

Create a RX gate

RXX(…)

Create a RXX gate

RY(…)

Create a RY gate

RYY(…)

Create a RYY gate

RZ(…)

Create a RZ gate

RZX(…)

Create a RZX gate

RZZ(…)

Create a RZZ gate

Reset(…)

Create a Reset node

S(…)

Create a S gate

SWAP(…)

Returns:

Shor_factorization(→ Tuple[bool, Tuple[int, int]])

Use Shor factorize integer num

SqiSWAP(…)

Returns:

T(…)

Create a T gate

Toffoli(…)

Create a Toffoli gate

U1(…)

Create a U1 gate

U2(…)

Create a U2 gate

U3(…)

Create a U3 gate

U4(…)

Create a U4 gate

UMA(→ QCircuit)

Quantum adder UMA module

VQG_CNOT_batch(→ Any)

variational quantum CNOT batch gates

VQG_CU_batch(→ Any)

variational quantum CU batch gates

VQG_CZ_batch(→ Any)

variational quantum CZ batch gates

VQG_H_batch(→ Any)

variational quantum H batch gates

VQG_I_batch(→ Any)

variational quantum I batch gates

VQG_SWAP_batch(→ Any)

variational quantum SWAP batch gates

VQG_S_batch(→ Any)

variational quantum S batch gates

VQG_SqiSWAP_batch(→ Any)

variational quantum SqiSWAP batch gates

VQG_T_batch(→ Any)

variational quantum T batch gates

VQG_U1_batch(→ Any)

variational quantum U1 batch gates

VQG_U2_batch(→ Any)

variational quantum U2 batch gates

VQG_U3_batch(→ Any)

variational quantum U3 batch gates

VQG_U4_batch(→ Any)

variational quantum U4 batch gates

VQG_X1_batch(→ Any)

variational quantum X1 batch gates

VQG_X_batch(→ Any)

variational quantum X batch gates

VQG_Y1_batch(→ Any)

variational quantum Y1 batch gates

VQG_Y_batch(→ Any)

variational quantum Y batch gates

VQG_Z1_batch(→ Any)

variational quantum Z1 batch gates

VQG_Z_batch(→ Any)

variational quantum Z batch gates

VQG_iSWAP_batch(→ Any)

variational quantum iSWAP batch gates

X(…)

Create a X gate

X1(…)

Create a X1 gate

Y(…)

Create a Y gate

Y1(…)

Create a Y1 gate

Z(…)

Create a Z gate

Z1(…)

Create a Z1 gate

accumulateProbability(→ List[float])

Accumulate the probability from a prob list

accumulate_probabilities(→ List[float])

Accumulate the probability from a prob list

accumulate_probability(→ List[float])

Accumulate the probability from a prob list

acos(→ var)

add(…)

all_cut_of_graph(→ float)

Generate graph of maxcut problem

amplitude_encode(…)

Encode the input double data to the amplitude of qubits

apply_QGate(…)

Apply QGate to qubits

asin(→ var)

assign(…)

atan(→ var)

average_gate_fidelity(…)

compare two quantum states , Get the state fidelity

bin_to_prog(→ bool)

Parse binary data transfor to quantum program

bind_data(→ QCircuit)

Args:

bind_nonnegative_data(→ QCircuit)

Args:

build_HHL_circuit(→ QCircuit)

build the quantum circuit for HHL algorithm to solve the target linear systems of equations : Ax = b

cAlloc(…)

Allocate a CBit

cAlloc_many(→ List[ClassicalCondition])

Allocate several CBits

cFree(→ None)

Free a CBit

cFree_all(…)

Free all cbits

calculate_quantum_volume(…)

calculate quantum volume

cast_qprog_qcircuit(→ QCircuit)

Cast QProg to QCircuit

cast_qprog_qgate(→ QGate)

Cast QProg to QGate

cast_qprog_qmeasure(→ QMeasure)

Cast QProg to QMeasure

circuit_layer(→ list)

Quantum circuit layering

circuit_optimizer(→ QProg)

Optimize QCircuit

circuit_optimizer_by_config(→ QProg)

QCircuit optimizer

comm_protocol_decode(→ Tuple[List[QProg], ...)

decode binary data to comm protocol prog list

comm_protocol_encode(…)

encode comm protocol data to binary data

constModAdd(→ QCircuit)

Args:

constModExp(→ QCircuit)

Args:

constModMul(→ QCircuit)

Args:

convert_binary_data_to_qprog(→ QProg)

Parse binary data to quantum program

convert_originir_str_to_qprog(→ list)

Trans OriginIR to QProg

convert_originir_to_qprog(→ list)

Read OriginIR file and trans to QProg

convert_qasm_string_to_qprog(→ list)

Trans QASM to QProg

convert_qasm_to_qprog(→ list)

Read QASM file and trans to QProg

convert_qprog_to_binary(…)

Store quantum program in binary file

convert_qprog_to_originir(→ str)

Args:

convert_qprog_to_qasm(→ str)

Convert QProg to QASM instruction string

convert_qprog_to_quil(→ str)

convert QProg to Quil instruction

cos(→ var)

count_gate(…)

Count quantum gate num under quantum program, quantum circuit

count_prog_info(…)

count quantum program info

count_qgate_num(…)

Count quantum gate num under quantum program

create_empty_circuit(→ QCircuit)

Create an empty QCircuit Container

create_empty_qprog(→ QProg)

Create an empty QProg Container

create_if_prog(…)

Create a classical quantum IfProg

create_while_prog(→ QWhileProg)

Create a WhileProg

crossEntropy(→ var)

decompose_multiple_control_qgate(…)

Decompose multiple control QGate

deep_copy(…)

del_weak_edge(→ None)

Delete weakly connected edges

del_weak_edge2(→ list)

Delete weakly connected edges

del_weak_edge3(→ list)

Delete weakly connected edges

destroy_quantum_machine(→ None)

Destroy a quantum machine

directly_run() → Dict[str, bool])

Directly run quantum prog

div(…)

dot(→ var)

double_gate_xeb(…)

double gate xeb

double_qubit_rb(…)

double qubit rb with origin chip

draw_qprog_latex(, itr_end)

Convert a quantum prog/circuit to latex source code, and save the source code to file in current path with name QCircuit.tex

draw_qprog_latex_with_clock(, itr_end)

Convert a quantum prog/circuit to latex source code with time sequence, and save the source code to file in current path with name QCircuit.tex

draw_qprog_text(, itr_end)

Convert a quantum prog/circuit to text-pic(UTF-8 code),

draw_qprog_text_with_clock(, itr_end)

Convert a quantum prog/circuit to text-pic(UTF-8 code) with time sequence,

dropout(→ var)

equal(…)

estimate_topology(→ float)

Evaluate topology performance

eval(…)

exp(→ var)

expMat(→ numpy.ndarray[numpy.complex128[m, n]])

calculate the matrix power of e

expand_linear_equations(…)

Extending linear equations to N dimension, N = 2 ^ n

fill_qprog_by_I(→ QProg)

Fill the input QProg by I gate, return a new quantum program

finalize(→ None)

Finalize the environment and destory global unique quantum machine.

fit_to_gbk(→ str)

Special character conversion

flatten(…)

Flatten quantum circuit

getAllocateCMem(→ int)

Deprecated, use get_allocate_cmem_num instead

getAllocateQubitNum(→ int)

Deprecated, use get_allocate_qubit_num instead

get_adjacent_qgate_type(→ List[NodeInfo])

Get the adjacent quantum gates's(the front one and the back one) typeinfo from QProg

get_all_used_qubits(→ QVec)

Get all the used quantum bits in the input prog

get_all_used_qubits_to_int(→ List[int])

Get all the used quantum bits addr in the input prog

get_allocate_cbits(→ List[ClassicalCondition])

Get allocated cbits of QuantumMachine

get_allocate_cmem_num(→ int)

get allocate cmem num

get_allocate_qubit_num(→ int)

get allocate qubit num

get_allocate_qubits(→ QVec)

Get allocated qubits of QuantumMachine

get_bin_data(→ List[int])

Get quantum program binary data

get_bin_str(→ str)

Transfor quantum program to string

get_circuit_optimal_topology(→ List[List[int]])

Get the optimal topology of the input circuit

get_clock_cycle(→ int)

Get quantum program clock cycle

get_complex_points(→ List[int])

Get complex points

get_double_gate_block_topology(→ List[List[int]])

get double gate block topology

get_matrix(, nodeitr_end)

Get the target matrix between the input two Nodeiters

get_prob_dict(→ Dict[str, float])

Get pmeasure result as dict

get_prob_list(→ List[float])

Get pmeasure result as list

get_qgate_num(…)

Count quantum gate num under quantum program

get_qprog_clock_cycle(→ int)

Get Quantum Program Clock Cycle

get_qstate(…)

get_sub_graph(→ List[int])

Get sub graph

get_tuple_list(→ List[Tuple[int, float]])

Get pmeasure result as tuple list

get_unitary(, nodeitr_end)

Get the target matrix between the input two Nodeiters

get_unsupport_qgate_num(→ int)

Count quantum program unsupported gate numner

getstat(→ Any)

Get the status of the Quantum machine

iSWAP(…)

Returns:

init(→ bool)

Init the global unique quantum machine at background.

init_quantum_machine(→ QuantumMachine)

Create and initialize a new quantum machine, and let it be global unique quantum machine

inverse(→ var)

isCarry(→ QCircuit)

Construct a circuit to determine if there is a carry

is_match_topology(→ bool)

Judge the QGate if match the target topologic structure of quantum circuit

is_supported_qgate_type(→ bool)

Judge if the target node is a QGate type

is_swappable(→ bool)

Judge the specialed two NodeIters in qprog whether can be exchanged

iterative_amplitude_estimation(→ float)

estimate the probability corresponding to the ground state |1> of the last bit

ldd_decompose(→ QProg)

Decompose multiple control QGate

log(→ var)

matrix_decompose(…)

Matrix decomposition

matrix_decompose_paulis(…)

decompose matrix into paulis combination

measure_all(…)

Create a list of measure node

mul(…)

originir_to_qprog(→ QProg)

Read OriginIR file and trans to QProg

pauli_combination_replace(→ List[Tuple[float, QCircuit]])

planarity_testing(→ bool)

planarity testing

pmeasure(→ List[Tuple[int, float]])

Get the probability distribution over qubits

pmeasure_no_index(→ List[float])

Get the probability distribution over qubits

poly(→ var)

print_matrix(→ str)

Print matrix element

prob_run_dict(→ Dict[str, float])

Run quantum program and get pmeasure result as dict

prob_run_list(→ List[float])

Run quantum program and get pmeasure result as list

prob_run_tuple_list(→ List[Tuple[int, float]])

Run quantum program and get pmeasure result as tuple list

prog_layer(→ Any)

prog_to_dag(→ QProgDAG)

qAlloc(…)

Allocate a qubits

qAlloc_many(→ List[Qubit])

Allocate several qubits

qFree(→ None)

Free a qubit

qFree_all(…)

Free a list of qubits

qop(…)

qop_pmeasure(→ var)

quantum_chip_adapter(→ list)

Quantum chip adaptive conversion

quantum_walk_alg(→ Any)

Build quantum-walk algorithm quantum circuit

quantum_walk_search(→ quantum_walk_search.list)

Use Quantum-walk Algorithm to search target data, return QProg and search_result

quick_measure(→ Dict[str, int])

Quick measure

random_qcircuit(→ QCircuit)

Generate random quantum circuit

random_qprog(→ QProg)

Generate random quantum program

recover_edges(→ List[List[int]])

Recover edges from the candidate edges

remap(→ QProg)

Source qunatum program is mapped to the target qubits

replace_complex_points(→ None)

Replacing complex points with subgraphs

run_with_configuration(…)

Run quantum program with configuration

sabre_mapping(…)

sabre mapping

sigmoid(→ var)

sin(→ var)

single_qubit_rb(…)

Single qubit rb with origin chip

softmax(→ var)

split_complex_points(→ List[Tuple[int, List[List[int]]]])

Splitting complex points into multiple points

stack(→ var)

state_fidelity(…)

compare two quantum states , Get the state fidelity

sub(…)

sum(→ var)

tan(→ var)

to_Quil(→ str)

Transform QProg to Quil instruction

to_originir(…)

Transform QProg to OriginIR string

topology_match(→ list)

Judge QProg/QCircuit matches the topology of the physical qubits

transform_binary_data_to_qprog(→ QProg)

Parse binary data trans to quantum program

transform_originir_to_qprog(→ QProg)

Transform OriginIR to QProg

transform_qprog_to_binary(…)

Save quantum program to file as binary data

transform_qprog_to_originir(→ str)

Quantum program transform to OriginIR string

transform_qprog_to_quil(→ str)

Transform QProg to Quil instruction

transform_to_base_qgate(…)

Basic quantum - gate conversion

transfrom_pauli_operator_to_matrix(→ List[complex])

transfrom pauli operator to matrix

transpose(→ var)

validate_double_qgate_type(→ list)

Get valid QGates and valid double bit QGate type

validate_single_qgate_type(→ list)

Get valid QGates and valid single bit QGate type

vector_dot(→ float)

Inner product of vector x and y

virtual_z_transform(→ QProg)

virtual z transform

class pyqpanda.pyQPanda.AbstractOptimizer(*args, **kwargs)[源代码]

quantum AbstractOptimizer class

exec() None[源代码]
getResult(*args, **kwargs) Any[源代码]
registerFunc(arg0: Callable[[List[float], List[float], int, int], Tuple[str, float]], arg1: List[float]) None[源代码]
setAdaptive(arg0: bool) None[源代码]
setCacheFile(arg0: str) None[源代码]
setDisp(arg0: bool) None[源代码]
setFatol(arg0: float) None[源代码]
setMaxFCalls(arg0: int) None[源代码]
setMaxIter(arg0: int) None[源代码]
setRestoreFromCacheFile(arg0: bool) None[源代码]
setXatol(arg0: float) None[源代码]
class pyqpanda.pyQPanda.AdaGradOptimizer(arg0: var, arg1: float, arg2: float, arg3: float)[源代码]

variational quantum AdaGradOptimizer

get_loss() float[源代码]
get_variables() List[var][源代码]
minimize(arg0: float, arg1: float, arg2: float) Optimizer[源代码]
run(arg0: List[var], arg1: int) bool[源代码]
class pyqpanda.pyQPanda.AdamOptimizer(arg0: var, arg1: float, arg2: float, arg3: float, arg4: float)[源代码]

variational quantum AdamOptimizer

get_loss() float[源代码]
get_variables() List[var][源代码]
minimize(arg0: float, arg1: float, arg2: float, arg3: float) Optimizer[源代码]
run(arg0: List[var], arg1: int) bool[源代码]
class pyqpanda.pyQPanda.Ansatz[源代码]
class pyqpanda.pyQPanda.Ansatz(arg0: QGate)
class pyqpanda.pyQPanda.Ansatz(arg0: AnsatzGate)
class pyqpanda.pyQPanda.Ansatz(ansatz: List[AnsatzGate], thetas: List[float] = [])
class pyqpanda.pyQPanda.Ansatz(ansatz_circuit: Ansatz, thetas: List[float] = [])
class pyqpanda.pyQPanda.Ansatz(circuit: QCircuit, thetas: List[float] = [])

quantum ansatz class

get_ansatz_list() List[AnsatzGate][源代码]
get_thetas_list() List[float][源代码]
insert(gate: QGate) None[源代码]
insert(gate: AnsatzGate) None
insert(gate: List[AnsatzGate]) None
insert(gate: QCircuit) None
insert(gate: Ansatz, thetas: List[float] = []) None
set_thetas(thetas: List[float]) None[源代码]
class pyqpanda.pyQPanda.AnsatzGate(arg0: AnsatzGateType, arg1: int)[源代码]
class pyqpanda.pyQPanda.AnsatzGate(arg0: AnsatzGateType, arg1: int, arg2: float)
class pyqpanda.pyQPanda.AnsatzGate(arg0: AnsatzGateType, arg1: int, arg2: float, arg3: int)

ansatz gate struct

control: int[源代码]
target: int[源代码]
theta: float[源代码]
type: AnsatzGateType[源代码]
class pyqpanda.pyQPanda.AnsatzGateType(value: int)[源代码]

Quantum ansatz gate type

Members:

AGT_X

AGT_H

AGT_RX

AGT_RY

AGT_RZ

property name: str[源代码]
property value: int[源代码]
AGT_H: ClassVar[AnsatzGateType] = Ellipsis[源代码]
AGT_RX: ClassVar[AnsatzGateType] = Ellipsis[源代码]
AGT_RY: ClassVar[AnsatzGateType] = Ellipsis[源代码]
AGT_RZ: ClassVar[AnsatzGateType] = Ellipsis[源代码]
AGT_X: ClassVar[AnsatzGateType] = Ellipsis[源代码]
class pyqpanda.pyQPanda.BackendType(value: int)[源代码]

Quantum machine backend type

Members:

CPU

GPU

CPU_SINGLE_THREAD

NOISE

MPS

property name: str[源代码]
property value: int[源代码]
CPU: ClassVar[BackendType] = Ellipsis[源代码]
CPU_SINGLE_THREAD: ClassVar[BackendType] = Ellipsis[源代码]
GPU: ClassVar[BackendType] = Ellipsis[源代码]
MPS: ClassVar[BackendType] = Ellipsis[源代码]
NOISE: ClassVar[BackendType] = Ellipsis[源代码]
class pyqpanda.pyQPanda.CBit(*args, **kwargs)[源代码]

quantum classical bit

getName() str[源代码]
class pyqpanda.pyQPanda.CPUQVM[源代码]

Bases: QuantumMachine

quantum machine cpu

get_prob_dict(qubit_list: QVec, select_max: int = -1) Dict[str, float][源代码]
get_prob_list(qubit_list: QVec, select_max: int = -1) List[float][源代码]
get_prob_tuple_list(qubit_list: QVec, select_max: int = -1) List[Tuple[int, float]][源代码]
init_qvm(arg0: bool) None[源代码]
init_qvm() None
pmeasure(qubit_list: QVec, select_max: int = -1) List[Tuple[int, float]][源代码]

Get the probability distribution over qubits

pmeasure_no_index(qubit_list: QVec) List[float][源代码]

Get the probability distribution over qubits

prob_run_dict(program: QProg, qubit_list: QVec, select_max: int = -1) Dict[str, float][源代码]
prob_run_dict(program: QProg, qubit_addr_list: List[int], select_max: int = -1) Dict[str, float]
prob_run_list(program: QProg, qubit_list: QVec, select_max: int = -1) List[float][源代码]
prob_run_list(program: QProg, qubit_addr_list: List[int], select_max: int = -1) List[float]
prob_run_tuple_list(program: QProg, qubit_list: QVec, select_max: int = -1) List[Tuple[int, float]][源代码]
prob_run_tuple_list(program: QProg, qubit_addr_list: List[int], select_max: int = -1) List[Tuple[int, float]]
quick_measure(qubit_list: QVec, shots: int) Dict[str, int][源代码]
set_max_threads(size: int) None[源代码]

set CPUQVM max thread size

class pyqpanda.pyQPanda.CPUSingleThreadQVM[源代码]

Bases: QuantumMachine

quantum machine class for cpu single thread

get_prob_dict(qubit_list: QVec, select_max: int = -1) Dict[str, float][源代码]
get_prob_list(qubit_list: QVec, select_max: int = -1) List[float][源代码]
get_prob_tuple_list(qubit_list: QVec, select_max: int = -1) List[Tuple[int, float]][源代码]
pmeasure(qubit_list: QVec, select_max: int = -1) List[Tuple[int, float]][源代码]

Get the probability distribution over qubits

pmeasure_no_index(qubit_list: QVec) List[float][源代码]

Get the probability distribution over qubits

prob_run_dict(program: QProg, qubit_list: QVec, select_max: int = -1) Dict[str, float][源代码]
prob_run_dict(program: QProg, qubit_addr_list: List[int], select_max: int = -1) Dict[str, float]
prob_run_list(program: QProg, qubit_list: QVec, select_max: int = -1) List[float][源代码]
prob_run_list(program: QProg, qubit_addr_list: List[int], select_max: int = -1) List[float]
prob_run_tuple_list(program: QProg, qubit_list: QVec, select_max: int = -1) List[Tuple[int, float]][源代码]
prob_run_tuple_list(program: QProg, qubit_addr_list: List[int], select_max: int = -1) List[Tuple[int, float]]
quick_measure(qubit_list: QVec, shots: int) Dict[str, int][源代码]
class pyqpanda.pyQPanda.ChipID(value: int)[源代码]

origin quantum real chip type

Members:

Simulation

WUYUAN_1

WUYUAN_2

WUYUAN_3

property name: str[源代码]
property value: int[源代码]
Simulation: ClassVar[ChipID] = Ellipsis[源代码]
WUYUAN_1: ClassVar[ChipID] = Ellipsis[源代码]
WUYUAN_2: ClassVar[ChipID] = Ellipsis[源代码]
WUYUAN_3: ClassVar[ChipID] = Ellipsis[源代码]
class pyqpanda.pyQPanda.ClassicalCondition(*args, **kwargs)[源代码]

Classical condition class Proxy class of cexpr class

c_and(arg0: int) ClassicalCondition[源代码]
c_and(arg0: ClassicalCondition) ClassicalCondition
c_not() ClassicalCondition[源代码]
c_or(arg0: int) ClassicalCondition[源代码]
c_or(arg0: ClassicalCondition) ClassicalCondition
get_val() int[源代码]

get value

set_val(arg0: int) None[源代码]

set value

class pyqpanda.pyQPanda.ClassicalProg(arg0: ClassicalCondition)[源代码]

quantum ClassicalProg

class pyqpanda.pyQPanda.CommProtocolConfig[源代码]
circuits_num: int[源代码]
open_error_mitigation: bool[源代码]
open_mapping: bool[源代码]
optimization_level: int[源代码]
shots: int[源代码]
class pyqpanda.pyQPanda.ComplexVertexSplitMethod(value: int)[源代码]

quantum complex vertex split method

Members:

METHOD_UNDEFINED

LINEAR

RING

property name: str[源代码]
property value: int[源代码]
LINEAR: ClassVar[ComplexVertexSplitMethod] = Ellipsis[源代码]
METHOD_UNDEFINED: ClassVar[ComplexVertexSplitMethod] = Ellipsis[源代码]
RING: ClassVar[ComplexVertexSplitMethod] = Ellipsis[源代码]
class pyqpanda.pyQPanda.DAGNodeType(value: int)[源代码]

Quantum dag node type

Members:

NUKNOW_SEQ_NODE_TYPE

MAX_GATE_TYPE

MEASURE

QUBIT

RESET

property name: str[源代码]
property value: int[源代码]
MAX_GATE_TYPE: ClassVar[DAGNodeType] = Ellipsis[源代码]
MEASURE: ClassVar[DAGNodeType] = Ellipsis[源代码]
NUKNOW_SEQ_NODE_TYPE: ClassVar[DAGNodeType] = Ellipsis[源代码]
QUBIT: ClassVar[DAGNodeType] = Ellipsis[源代码]
RESET: ClassVar[DAGNodeType] = Ellipsis[源代码]
class pyqpanda.pyQPanda.DecompositionMode(value: int)[源代码]

Quantum matrix decomposition mode

Members:

QR

HOUSEHOLDER_QR

QSDecomposition

CSDecomposition

property name: str[源代码]
property value: int[源代码]
CSDecomposition: ClassVar[DecompositionMode] = Ellipsis[源代码]
HOUSEHOLDER_QR: ClassVar[DecompositionMode] = Ellipsis[源代码]
QR: ClassVar[DecompositionMode] = Ellipsis[源代码]
QSDecomposition: ClassVar[DecompositionMode] = Ellipsis[源代码]
class pyqpanda.pyQPanda.DensityMatrixSimulator[源代码]

Bases: QuantumMachine

simulator for density matrix

get_density_matrix(prog: QProg) numpy.ndarray[numpy.complex128[m, n]][源代码]

Run quantum program and get full density matrix

Args:

prog: quantum program

Returns:

full density matrix

Raises:

run_fail: An error occurred in get_density_matrix

get_expectation(prog: QProg, hamiltonian: List[Tuple[Dict[int, str], float]], qubits: QVec) float[源代码]
get_expectation(prog: QProg, hamiltonian: List[Tuple[Dict[int, str], float]], qubits: List[int]) float

Run quantum program and hamiltonian expection for current qubits

Args:

prog: quantum program hamiltonian: QHamiltonian qubits: select qubits

Returns:

hamiltonian expection for current qubits

Raises:

run_fail: An error occurred in get_expectation

get_probabilities(prog: QProg) List[float][源代码]
get_probabilities(prog: QProg, qubits: QVec) List[float]
get_probabilities(prog: QProg, qubits: List[int]) List[float]
get_probabilities(prog: QProg, indices: List[str]) List[float]

Run quantum program and get all indices probabilities for current binary indices

Args:

prog: quantum program indices: select binary indices

Returns:

probabilities result of quantum program

Raises:

run_fail: An error occurred in get_probabilities

get_probability(prog: QProg, index: int) float[源代码]
get_probability(prog: QProg, index: str) float

Run quantum program and get index probability

Args:

prog: quantum program index: measure index in [0,2^N - 1]

Returns:

probability result of quantum program

Raises:

run_fail: An error occurred in get_probability

get_reduced_density_matrix(prog: QProg, qubits: QVec) numpy.ndarray[numpy.complex128[m, n]][源代码]
get_reduced_density_matrix(prog: QProg, qubits: List[int]) numpy.ndarray[numpy.complex128[m, n]]

Run quantum program and get density matrix for current qubits

Args:

prog: quantum program qubits: quantum program select qubits

Returns:

density matrix

Raises:

run_fail: An error occurred in get_reduced_density_matrix

init_qvm(is_double_precision: bool = True) None[源代码]
set_noise_model(arg0: numpy.ndarray[numpy.complex128[m, n]]) None[源代码]
set_noise_model(arg0: numpy.ndarray[numpy.complex128[m, n]], arg1: List[GateType]) None
set_noise_model(arg0: List[numpy.ndarray[numpy.complex128[m, n]]]) None
set_noise_model(arg0: List[numpy.ndarray[numpy.complex128[m, n]]], arg1: List[GateType]) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float) None
set_noise_model(arg0: NoiseModel, arg1: List[GateType], arg2: float) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float, arg3: QVec) None
set_noise_model(arg0: NoiseModel, arg1: List[GateType], arg2: float, arg3: QVec) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float, arg3: List[QVec]) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float, arg3: float, arg4: float) None
set_noise_model(arg0: NoiseModel, arg1: List[GateType], arg2: float, arg3: float, arg4: float) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float, arg3: float, arg4: float, arg5: QVec) None
set_noise_model(arg0: NoiseModel, arg1: List[GateType], arg2: float, arg3: float, arg4: float, arg5: QVec) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float, arg3: float, arg4: float, arg5: List[QVec]) None
class pyqpanda.pyQPanda.DoubleGateTransferType(value: int)[源代码]

Quantum double gate transfer type

Members:

DOUBLE_GATE_INVALID

DOUBLE_BIT_GATE

property name: str[源代码]
property value: int[源代码]
DOUBLE_BIT_GATE: ClassVar[DoubleGateTransferType] = Ellipsis[源代码]
DOUBLE_GATE_INVALID: ClassVar[DoubleGateTransferType] = Ellipsis[源代码]
class pyqpanda.pyQPanda.Encode[源代码]

quantum amplitude encode

amplitude_encode(qubit: QVec, data: List[float]) None[源代码]
amplitude_encode(qubit: QVec, data: List[complex]) None
amplitude_encode_recursive(qubit: QVec, data: List[float]) None[源代码]
amplitude_encode_recursive(qubit: QVec, data: List[complex]) None

Encode by amplitude recursive

Args:

QVec: qubits QStat: amplitude

Returns:

circuit

Raises:

run_fail: An error occurred in get amplitude_encode_recursive

angle_encode(qubit: QVec, data: List[float], gate_type: GateType = GateType.RY_GATE) None[源代码]

Encode by angle

Args:

QVec: qubits prob_vec: data

Returns:

circuit

Raises:

run_fail: An error occurred in get angle_encode

approx_mps(qubit: QVec, data: List[float], layers: int = 3, sweeps: int = 100, double2float: bool = False) None[源代码]
approx_mps(qubit: QVec, data: List[complex], layers: int = 3, sweeps: int = 100) None

approx mps encode

Args:

Qubit: qubits data: std::vector<qcomplex_t> int: layer int: step

Returns:

circuit

Raises:

run_fail: An error occurred in approx_mps

basic_encode(qubit: QVec, data: str) None[源代码]

basic_encode

Args:

QVec: qubits string: data

Returns:

circuit

Raises:

run_fail: An error occurred in basic_encode

bid_amplitude_encode(qubit: QVec, data: List[float], split: int = 0) None[源代码]

Encode by bid

Args:

QVec: qubits QStat: amplitude split: int

Returns:

circuit

Raises:

run_fail: An error occurred in bid_amplitude_encode

dc_amplitude_encode(qubit: QVec, data: List[float]) None[源代码]

Encode by dc amplitude

Args:

QVec: qubits QStat: amplitude

Returns:

circuit

Raises:

run_fail: An error occurred in dc_amplitude_encode

dense_angle_encode(qubit: QVec, data: List[float]) None[源代码]

Encode by dense angle

Args:

QVec: qubits prob_vec: data

Returns:

circuit

Raises:

run_fail: An error occurred in dense_angle_encode

ds_quantum_state_preparation(qubit: QVec, data: Dict[str, float]) None[源代码]
ds_quantum_state_preparation(qubit: QVec, data: Dict[str, complex]) None
ds_quantum_state_preparation(qubit: QVec, data: List[float]) None
ds_quantum_state_preparation(qubit: QVec, data: List[complex]) None
efficient_sparse(qubit: QVec, data: Dict[str, float]) None[源代码]
efficient_sparse(qubit: QVec, data: Dict[str, complex]) None
efficient_sparse(qubit: QVec, data: List[float]) None
efficient_sparse(qubit: QVec, data: List[complex]) None
get_circuit() QCircuit[源代码]
get_fidelity(data: List[float]) float[源代码]
get_fidelity(data: List[complex]) float
get_fidelity(data: List[float]) float
get_out_qubits() QVec[源代码]
iqp_encode(qubit: QVec, data: List[float], control_list: List[Tuple[int, int]] = [], bool_inverse: bool = False, repeats: int = 1) None[源代码]

Encode by iqp

Args:

QVec: qubits prob_vec: data list: control_list bool: bool_inverse int: repeats

Returns:

circuit

Raises:

run_fail: An error occurred in iqp_encode

schmidt_encode(qubit: QVec, data: List[float], cutoff: float) None[源代码]

Encode by schmidt

Args:

QVec: qubits QStat: amplitude double: cut_off

Returns:

circuit

Raises:

run_fail: An error occurred in schmidt_encode

sparse_isometry(qubit: QVec, data: Dict[str, float]) None[源代码]
sparse_isometry(qubit: QVec, data: Dict[str, complex]) None
sparse_isometry(qubit: QVec, data: List[float]) None
sparse_isometry(qubit: QVec, data: List[complex]) None
class pyqpanda.pyQPanda.ErrorCode(value: int)[源代码]

pliot error code

Members:

NO_ERROR_FOUND

DATABASE_ERROR

ORIGINIR_ERROR

JSON_FIELD_ERROR

BACKEND_CALC_ERROR

ERR_TASK_BUF_OVERFLOW

EXCEED_MAX_QUBIT

ERR_UNSUPPORT_BACKEND_TYPE

EXCEED_MAX_CLOCK

ERR_UNKNOW_TASK_TYPE

ERR_QVM_INIT_FAILED

ERR_QCOMPILER_FAILED

ERR_PRE_ESTIMATE

ERR_MATE_GATE_CONFIG

ERR_FIDELITY_MATRIX

ERR_QST_PROG

ERR_EMPTY_PROG

ERR_QUBIT_SIZE

ERR_QUBIT_TOPO

ERR_QUANTUM_CHIP_PROG

ERR_REPEAT_MEASURE

ERR_OPERATOR_DB

ERR_TASK_STATUS_BUF_OVERFLOW

ERR_BACKEND_CHIP_TASK_SOCKET_WRONG

CLUSTER_SIMULATE_CALC_ERR

ERR_SCHEDULE_CHIP_TOPOLOGY_SUPPORTED

ERR_TASK_CONFIG

ERR_NOT_FOUND_APP_ID

ERR_NOT_FOUND_TASK_ID

ERR_PARSER_SUB_TASK_RESULT

ERR_SYS_CALL_TIME_OUT

ERR_TASK_TERMINATED

ERR_INVALID_URL

ERR_PARAMETER

ERR_QPROG_LENGTH

ERR_CHIP_OFFLINE

UNDEFINED_ERROR

ERR_SUB_GRAPH_OUT_OF_RANGE

ERR_TCP_INIT_FATLT

ERR_TCP_SERVER_HALT

CLUSTER_BASE

property name: str[源代码]
property value: int[源代码]
BACKEND_CALC_ERROR: ClassVar[ErrorCode] = Ellipsis[源代码]
CLUSTER_BASE: ClassVar[ErrorCode] = Ellipsis[源代码]
CLUSTER_SIMULATE_CALC_ERR: ClassVar[ErrorCode] = Ellipsis[源代码]
DATABASE_ERROR: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_BACKEND_CHIP_TASK_SOCKET_WRONG: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_CHIP_OFFLINE: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_EMPTY_PROG: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_FIDELITY_MATRIX: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_INVALID_URL: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_MATE_GATE_CONFIG: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_NOT_FOUND_APP_ID: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_NOT_FOUND_TASK_ID: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_OPERATOR_DB: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_PARAMETER: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_PARSER_SUB_TASK_RESULT: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_PRE_ESTIMATE: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_QCOMPILER_FAILED: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_QPROG_LENGTH: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_QST_PROG: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_QUANTUM_CHIP_PROG: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_QUBIT_SIZE: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_QUBIT_TOPO: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_QVM_INIT_FAILED: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_REPEAT_MEASURE: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_SCHEDULE_CHIP_TOPOLOGY_SUPPORTED: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_SUB_GRAPH_OUT_OF_RANGE: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_SYS_CALL_TIME_OUT: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_TASK_BUF_OVERFLOW: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_TASK_CONFIG: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_TASK_STATUS_BUF_OVERFLOW: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_TASK_TERMINATED: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_TCP_INIT_FATLT: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_TCP_SERVER_HALT: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_UNKNOW_TASK_TYPE: ClassVar[ErrorCode] = Ellipsis[源代码]
ERR_UNSUPPORT_BACKEND_TYPE: ClassVar[ErrorCode] = Ellipsis[源代码]
EXCEED_MAX_CLOCK: ClassVar[ErrorCode] = Ellipsis[源代码]
EXCEED_MAX_QUBIT: ClassVar[ErrorCode] = Ellipsis[源代码]
JSON_FIELD_ERROR: ClassVar[ErrorCode] = Ellipsis[源代码]
NO_ERROR_FOUND: ClassVar[ErrorCode] = Ellipsis[源代码]
ORIGINIR_ERROR: ClassVar[ErrorCode] = Ellipsis[源代码]
UNDEFINED_ERROR: ClassVar[ErrorCode] = Ellipsis[源代码]
class pyqpanda.pyQPanda.Fusion[源代码]

quantum fusion operation

aggregate_operations(circuit: QCircuit) None[源代码]
aggregate_operations(qprog: QProg) None
class pyqpanda.pyQPanda.GateType(value: int)[源代码]

quantum gate type

Members:

GATE_NOP

GATE_UNDEFINED

P0_GATE

P1_GATE

PAULI_X_GATE

PAULI_Y_GATE

PAULI_Z_GATE

X_HALF_PI

Y_HALF_PI

Z_HALF_PI

HADAMARD_GATE

T_GATE

S_GATE

P_GATE

CP_GATE

RX_GATE

RY_GATE

RZ_GATE

RXX_GATE

RYY_GATE

RZZ_GATE

RZX_GATE

U1_GATE

U2_GATE

U3_GATE

U4_GATE

CU_GATE

CNOT_GATE

CZ_GATE

MS_GATE

CPHASE_GATE

ISWAP_THETA_GATE

ISWAP_GATE

SQISWAP_GATE

SWAP_GATE

TWO_QUBIT_GATE

P00_GATE

P11_GATE

TOFFOLI_GATE

ORACLE_GATE

I_GATE

BARRIER_GATE

RPHI_GATE

property name: str[源代码]
property value: int[源代码]
BARRIER_GATE: ClassVar[GateType] = Ellipsis[源代码]
CNOT_GATE: ClassVar[GateType] = Ellipsis[源代码]
CPHASE_GATE: ClassVar[GateType] = Ellipsis[源代码]
CP_GATE: ClassVar[GateType] = Ellipsis[源代码]
CU_GATE: ClassVar[GateType] = Ellipsis[源代码]
CZ_GATE: ClassVar[GateType] = Ellipsis[源代码]
GATE_NOP: ClassVar[GateType] = Ellipsis[源代码]
GATE_UNDEFINED: ClassVar[GateType] = Ellipsis[源代码]
HADAMARD_GATE: ClassVar[GateType] = Ellipsis[源代码]
ISWAP_GATE: ClassVar[GateType] = Ellipsis[源代码]
ISWAP_THETA_GATE: ClassVar[GateType] = Ellipsis[源代码]
I_GATE: ClassVar[GateType] = Ellipsis[源代码]
MS_GATE: ClassVar[GateType] = Ellipsis[源代码]
ORACLE_GATE: ClassVar[GateType] = Ellipsis[源代码]
P00_GATE: ClassVar[GateType] = Ellipsis[源代码]
P0_GATE: ClassVar[GateType] = Ellipsis[源代码]
P11_GATE: ClassVar[GateType] = Ellipsis[源代码]
P1_GATE: ClassVar[GateType] = Ellipsis[源代码]
PAULI_X_GATE: ClassVar[GateType] = Ellipsis[源代码]
PAULI_Y_GATE: ClassVar[GateType] = Ellipsis[源代码]
PAULI_Z_GATE: ClassVar[GateType] = Ellipsis[源代码]
P_GATE: ClassVar[GateType] = Ellipsis[源代码]
RPHI_GATE: ClassVar[GateType] = Ellipsis[源代码]
RXX_GATE: ClassVar[GateType] = Ellipsis[源代码]
RX_GATE: ClassVar[GateType] = Ellipsis[源代码]
RYY_GATE: ClassVar[GateType] = Ellipsis[源代码]
RY_GATE: ClassVar[GateType] = Ellipsis[源代码]
RZX_GATE: ClassVar[GateType] = Ellipsis[源代码]
RZZ_GATE: ClassVar[GateType] = Ellipsis[源代码]
RZ_GATE: ClassVar[GateType] = Ellipsis[源代码]
SQISWAP_GATE: ClassVar[GateType] = Ellipsis[源代码]
SWAP_GATE: ClassVar[GateType] = Ellipsis[源代码]
S_GATE: ClassVar[GateType] = Ellipsis[源代码]
TOFFOLI_GATE: ClassVar[GateType] = Ellipsis[源代码]
TWO_QUBIT_GATE: ClassVar[GateType] = Ellipsis[源代码]
T_GATE: ClassVar[GateType] = Ellipsis[源代码]
U1_GATE: ClassVar[GateType] = Ellipsis[源代码]
U2_GATE: ClassVar[GateType] = Ellipsis[源代码]
U3_GATE: ClassVar[GateType] = Ellipsis[源代码]
U4_GATE: ClassVar[GateType] = Ellipsis[源代码]
X_HALF_PI: ClassVar[GateType] = Ellipsis[源代码]
Y_HALF_PI: ClassVar[GateType] = Ellipsis[源代码]
Z_HALF_PI: ClassVar[GateType] = Ellipsis[源代码]
class pyqpanda.pyQPanda.HHLAlg(arg0: QuantumMachine)[源代码]

quantum hhl algorithm class

check_QPE_result() str[源代码]

check QPE result

get_amplification_factor() float[源代码]

get_amplification_factor

get_ancillary_qubit() QVec[源代码]

get_ancillary_qubit

get_hhl_circuit(matrix_A: List[complex], data_b: List[float], precision_cnt: int = 0) QCircuit[源代码]
get_qubit_for_QFT() List[Qubit][源代码]

get_qubit_for_QFT

get_qubit_for_b() List[Qubit][源代码]

get_qubit_for_b

query_uesed_qubit_num() int[源代码]

query_uesed_qubit_num

class pyqpanda.pyQPanda.LATEX_GATE_TYPE(value: int)[源代码]

Quantum latex gate type

Members:

GENERAL_GATE

CNOT_GATE

SWAP_GATE

property name: str[源代码]
property value: int[源代码]
CNOT_GATE: ClassVar[LATEX_GATE_TYPE] = Ellipsis[源代码]
GENERAL_GATE: ClassVar[LATEX_GATE_TYPE] = Ellipsis[源代码]
SWAP_GATE: ClassVar[LATEX_GATE_TYPE] = Ellipsis[源代码]
class pyqpanda.pyQPanda.LatexMatrix[源代码]

Generate quantum circuits latex src code can be compiled on latex package 'qcircuit' circuits element treated as matrix element in latex syntax

qcircuit package tutorial [https://physics.unm.edu/CQuIC/Qcircuit/Qtutorial.pdf]

insert_barrier(rows: List[int], from_col: int) int[源代码]
Args:

rows: rows need be barriered, may not continus

insert_gate(target_rows: List[int], ctrl_rows: List[int], from_col: int, gate_type: LATEX_GATE_TYPE, gate_name: str = '', dagger: bool = False, param: str = '') int[源代码]

Insert a gate into circute

Args:

target_rows: gate targets row of latex matrix ctrl_rows from_col: gate wanted col pos, but there may be not enough zone to put gate gate_type: enum type of LATEX_GATE_TYPE gate_name dagger: dagger flag param: gate param str

Returns:

int: real col num. if there is no enough zone to put gate at 'from_col', we will find suitable col to put gate after 'from_col'

insert_measure(q_row: int, c_row: int, from_col: int) int[源代码]
insert_reset(q_row: int, from_col: int) int[源代码]
insert_timeseq(t_col: int, time_seq: int) None[源代码]

Beware we do not check col num, may cause overwrite. user must take care col num self

set_label(qubit_label: Dict[int, str], cbit_label: Dict[int, str] = {}, time_seq_label: str = '', head: bool = True) None[源代码]

Set Label at left most head col or right most tail col label can be reseted at any time

Args:
qubit_label: label for qwire left most head label, at row, in latex syntax. not given row will keep empty

eg. {0: 'q_{1}', 2:'q_{2}'}

cbit_label: classic label string, support latex str time_seq_label: if given, set time squence lable head: if true, label append head; false, append at tail

Add a logo string

str(with_time: bool = False) str[源代码]

return final latex source code, can be called at any time

class pyqpanda.pyQPanda.MPSQVM[源代码]

Bases: QuantumMachine

quantum matrix product state machine class

add_single_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float) None[源代码]
add_single_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float, arg3: float, arg4: float) None
get_prob_dict(qubit_list: QVec, select_max: int = -1) Dict[str, float][源代码]

Get pmeasure result as dict

Args:

qubit_list: pmeasure qubits list select_max: max returned element num in returnd tuple, should in [-1, 1<<len(qubit_list)]

default is -1, means no limit

Returns:

measure result of quantum machine

Raises:

run_fail: An error occurred in get_prob_dict

get_prob_list(qubit_list: QVec, select_max: int = -1) List[float][源代码]

Get pmeasure result as list

Args:

qubit_list: pmeasure qubits list select_max: max returned element num in returnd tuple, should in [-1, 1<<len(qubit_list)]

default is -1, means no limit

Returns:

measure result of quantum machine

Raises:

run_fail: An error occurred in get_prob_list

get_prob_tuple_list(qubit_list: QVec, select_max: int = -1) List[Tuple[int, float]][源代码]

Get pmeasure result as list

Args:

qubit_list: pmeasure qubits list select_max: max returned element num in returnd tuple, should in [-1, 1<<len(qubit_list)]

default is -1, means no limit

Returns:

measure result of quantum machine

Raises:

run_fail: An error occurred in get_prob_tuple_list

pmeasure(qubit_list: QVec, select_max: int = -1) List[Tuple[int, float]][源代码]

Get the probability distribution over qubits

Args:

qubit_list: qubit list to measure select_max: max returned element num in returnd tuple, should in [-1, 1<<len(qubit_list)]

default is -1, means no limit

Returns:

measure result of quantum machine in tuple form

pmeasure_bin_index(program: QProg, string: str) complex[源代码]

pmeasure bin index quantum state amplitude

Args:

string : bin string

Returns:

complex : bin amplitude

Raises:

run_fail: An error occurred in pmeasure_bin_index

pmeasure_bin_subset(program: QProg, string_list: List[str]) List[complex][源代码]

pmeasure quantum state amplitude subset

Args:

list : bin state string list

Returns:

list : bin amplitude result list

Raises:

run_fail: An error occurred in pmeasure_bin_subset

pmeasure_dec_index(program: QProg, string: str) complex[源代码]

pmeasure dec index quantum state amplitude

Args:

string : dec string

Returns:

complex : dec amplitude

Raises:

run_fail: An error occurred in pmeasure_dec_index

pmeasure_dec_subset(program: QProg, string_list: List[str]) List[complex][源代码]

pmeasure quantum state amplitude subset

Args:

list : dec state string list

Returns:

list : dec amplitude result list

Raises:

run_fail: An error occurred in pmeasure_dec_subset

pmeasure_no_index(qubit_list: QVec) List[float][源代码]

Get the probability distribution over qubits

Args:

qubit_list: qubit list to measure

Returns:

measure result of quantum machine in list form

prob_run_dict(program: QProg, qubit_list: QVec, select_max: int = -1) Dict[str, float][源代码]

Run quantum program and get pmeasure result as dict

Args:

qprog: quantum program qubit_list: pmeasure qubits list select_max: max returned element num in returnd tuple, should in [-1, 1<<len(qubit_list)]

default is -1, means no limit

Returns:

measure result of quantum machine

Raises:

run_fail: An error occurred in measure quantum program

prob_run_list(program: QProg, qubit_list: QVec, select_max: int = -1) List[float][源代码]

Run quantum program and get pmeasure result as list

Args:

qprog: quantum program qubit_list: pmeasure qubits list select_max: max returned element num in returnd tuple, should in [-1, 1<<len(qubit_list)]

default is -1, means no limit

Returns:

measure result of quantum machine

Raises:

run_fail: An error occurred in measure quantum program

prob_run_tuple_list(program: QProg, qubit_list: QVec, select_max: int = -1) List[Tuple[int, float]][源代码]

Run quantum program and get pmeasure result as tuple list

Args:

qprog: quantum program qubit_list: pmeasure qubits list select_max: max returned element num in returnd tuple, should in [-1, 1<<len(qubit_list)]

default is -1, means no limit

Returns:

measure result of quantum machine

Raises:

run_fail: An error occurred in prob_run_tuple_list

quick_measure(qubit_list: QVec, shots: int) Dict[str, int][源代码]

Quick measure

Args:

qubit_list: qubit list to measure shots: the repeat num of measure operate

Returns:

result of quantum program

Raises:

run_fail: An error occurred in measure quantum program

set_measure_error(arg0: NoiseModel, arg1: float) None[源代码]
set_measure_error(arg0: NoiseModel, arg1: float, arg2: float, arg3: float) None
set_mixed_unitary_error(arg0: GateType, arg1: List[List[complex]], arg2: List[QVec]) None[源代码]
set_mixed_unitary_error(arg0: GateType, arg1: List[List[complex]], arg2: List[float], arg3: List[QVec]) None
set_mixed_unitary_error(arg0: GateType, arg1: List[List[complex]]) None
set_mixed_unitary_error(arg0: GateType, arg1: List[List[complex]], arg2: List[float]) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float) None[源代码]
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float, arg3: List[QVec]) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float, arg3: float, arg4: float) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float, arg3: float, arg4: float, arg5: List[QVec]) None
set_readout_error(readout_params: List[List[float]], qubits: QVec) None[源代码]
set_reset_error(reset_0_param: float, reset_1_param: float) None[源代码]
set_rotation_error(param: float) None[源代码]
class pyqpanda.pyQPanda.MomentumOptimizer(arg0: var, arg1: float, arg2: float)[源代码]

variational quantum MomentumOptimizer

get_loss() float[源代码]
get_variables() List[var][源代码]
minimize(arg0: float, arg1: float) Optimizer[源代码]
run(arg0: List[var], arg1: int) bool[源代码]
class pyqpanda.pyQPanda.NodeInfo[源代码]
class pyqpanda.pyQPanda.NodeInfo(iter: NodeIter, target_qubits: QVec, control_qubits: QVec, type: int, dagger: bool)

Detailed information of a QProg node

m_cbits: List[int][源代码]
m_control_qubits: QVec[源代码]
m_gate_type: GateType[源代码]
m_is_dagger: bool[源代码]
m_iter: NodeIter[源代码]
m_name: str[源代码]
m_node_type: NodeType[源代码]
m_params: List[float][源代码]
m_target_qubits: QVec[源代码]
reset() None[源代码]
class pyqpanda.pyQPanda.NodeIter[源代码]

quantum node iter

get_next() NodeIter[源代码]
get_node_type() NodeType[源代码]
get_pre() NodeIter[源代码]
class pyqpanda.pyQPanda.NodeType(value: int)[源代码]

quantum node type

Members:

NODE_UNDEFINED

GATE_NODE

CIRCUIT_NODE

PROG_NODE

MEASURE_GATE

WHILE_START_NODE

QIF_START_NODE

CLASS_COND_NODE

RESET_NODE

property name: str[源代码]
property value: int[源代码]
CIRCUIT_NODE: ClassVar[NodeType] = Ellipsis[源代码]
CLASS_COND_NODE: ClassVar[NodeType] = Ellipsis[源代码]
GATE_NODE: ClassVar[NodeType] = Ellipsis[源代码]
MEASURE_GATE: ClassVar[NodeType] = Ellipsis[源代码]
NODE_UNDEFINED: ClassVar[NodeType] = Ellipsis[源代码]
PROG_NODE: ClassVar[NodeType] = Ellipsis[源代码]
QIF_START_NODE: ClassVar[NodeType] = Ellipsis[源代码]
RESET_NODE: ClassVar[NodeType] = Ellipsis[源代码]
WHILE_START_NODE: ClassVar[NodeType] = Ellipsis[源代码]
class pyqpanda.pyQPanda.Noise[源代码]

Quantum machine for noise simulation

add_mixed_unitary_error(gate_types: GateType, unitary_matrices: List[List[complex]], probs: List[float]) None[源代码]
add_mixed_unitary_error(gate_types: GateType, unitary_matrices: List[List[complex]], probs: List[float], qubits: QVec) None
add_mixed_unitary_error(gate_types: GateType, unitary_matrices: List[List[complex]], probs: List[float], qubits: List[QVec]) None
add_noise_model(noise_model: NoiseModel, gate_type: GateType, prob: float) None[源代码]
add_noise_model(noise_model: NoiseModel, gate_types: List[GateType], prob: float) None
add_noise_model(noise_model: NoiseModel, gate_type: GateType, prob: float, qubits: QVec) None
add_noise_model(noise_model: NoiseModel, gate_types: List[GateType], prob: float, qubits: QVec) None
add_noise_model(noise_model: NoiseModel, gate_type: GateType, prob: float, qubits: List[QVec]) None
add_noise_model(noise_model: NoiseModel, gate_type: GateType, t1: float, t2: float, t_gate: float) None
add_noise_model(noise_model: NoiseModel, gate_types: List[GateType], t1: float, t2: float, t_gate: float) None
add_noise_model(noise_model: NoiseModel, gate_type: GateType, t1: float, t2: float, t_gate: float, qubits: QVec) None
add_noise_model(noise_model: NoiseModel, gate_types: List[GateType], t1: float, t2: float, t_gate: float, qubits: QVec) None
add_noise_model(noise_model: NoiseModel, gate_type: GateType, t1: float, t2: float, t_gate: float, qubits: List[QVec]) None
set_measure_error(noise_model: NoiseModel, prob: float, qubits: QVec = ...) None[源代码]
set_measure_error(noise_model: NoiseModel, t1: float, t2: float, t_gate: float, qubits: QVec = ...) None
set_readout_error(prob_list: List[List[float]], qubits: QVec = ...) None[源代码]
set_reset_error(p0: float, p1: float, qubits: QVec) None[源代码]
set_rotation_error(error: float) None[源代码]
class pyqpanda.pyQPanda.NoiseModel(value: int)[源代码]

noise model type

Members:

DAMPING_KRAUS_OPERATOR

DECOHERENCE_KRAUS_OPERATOR

DEPHASING_KRAUS_OPERATOR

PAULI_KRAUS_MAP

BITFLIP_KRAUS_OPERATOR

DEPOLARIZING_KRAUS_OPERATOR

BIT_PHASE_FLIP_OPRATOR

PHASE_DAMPING_OPRATOR

property name: str[源代码]
property value: int[源代码]
BITFLIP_KRAUS_OPERATOR: ClassVar[NoiseModel] = Ellipsis[源代码]
BIT_PHASE_FLIP_OPRATOR: ClassVar[NoiseModel] = Ellipsis[源代码]
DAMPING_KRAUS_OPERATOR: ClassVar[NoiseModel] = Ellipsis[源代码]
DECOHERENCE_KRAUS_OPERATOR: ClassVar[NoiseModel] = Ellipsis[源代码]
DEPHASING_KRAUS_OPERATOR: ClassVar[NoiseModel] = Ellipsis[源代码]
DEPOLARIZING_KRAUS_OPERATOR: ClassVar[NoiseModel] = Ellipsis[源代码]
PAULI_KRAUS_MAP: ClassVar[NoiseModel] = Ellipsis[源代码]
PHASE_DAMPING_OPRATOR: ClassVar[NoiseModel] = Ellipsis[源代码]
class pyqpanda.pyQPanda.NoiseQVM[源代码]

Bases: QuantumMachine

quantum machine class for simulate noise prog

initQVM(arg0: dict) None[源代码]

init quantum virtual machine

init_qvm(json_config: dict) None[源代码]
init_qvm() None

init quantum virtual machine

set_max_threads(size: int) None[源代码]

set NoiseQVM max thread size

set_measure_error(model: NoiseModel, prob: float, qubits: QVec = ...) None[源代码]
set_measure_error(model: NoiseModel, T1: float, T2: float, t_gate: float, qubits: QVec = ...) None
set_mixed_unitary_error(arg0: GateType, arg1: List[List[complex]], arg2: List[float]) None[源代码]
set_mixed_unitary_error(arg0: GateType, arg1: List[List[complex]], arg2: List[float], arg3: QVec) None
set_mixed_unitary_error(arg0: GateType, arg1: List[List[complex]], arg2: List[float], arg3: List[QVec]) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float) None[源代码]
set_noise_model(arg0: NoiseModel, arg1: List[GateType], arg2: float) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float, arg3: QVec) None
set_noise_model(arg0: NoiseModel, arg1: List[GateType], arg2: float, arg3: QVec) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float, arg3: List[QVec]) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float, arg3: float, arg4: float) None
set_noise_model(arg0: NoiseModel, arg1: List[GateType], arg2: float, arg3: float, arg4: float) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float, arg3: float, arg4: float, arg5: QVec) None
set_noise_model(arg0: NoiseModel, arg1: List[GateType], arg2: float, arg3: float, arg4: float, arg5: QVec) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float, arg3: float, arg4: float, arg5: List[QVec]) None
set_readout_error(probs_list: List[List[float]], qubits: QVec = ...) None[源代码]
set_reset_error(p0: float, p1: float, qubits: QVec = ...) None[源代码]
set_rotation_error(arg0: float) None[源代码]
class pyqpanda.pyQPanda.Optimizer(*args, **kwargs)[源代码]

variational quantum Optimizer class

get_loss() float[源代码]
get_variables() List[var][源代码]
run(arg0: List[var], arg1: int) bool[源代码]
class pyqpanda.pyQPanda.OptimizerFactory[源代码]

quantum OptimizerFactory class

makeOptimizer() AbstractOptimizer[源代码]
makeOptimizer() AbstractOptimizer

Please input the Optimizer's name(string)

class pyqpanda.pyQPanda.OptimizerMode(value: int)[源代码]

variational quantum OptimizerMode

Members:

property name: str[源代码]
property value: int[源代码]
class pyqpanda.pyQPanda.OptimizerType(value: int)[源代码]

quantum OptimizerType

Members:

NELDER_MEAD

POWELL

GRADIENT

property name: str[源代码]
property value: int[源代码]
GRADIENT: ClassVar[OptimizerType] = Ellipsis[源代码]
NELDER_MEAD: ClassVar[OptimizerType] = Ellipsis[源代码]
POWELL: ClassVar[OptimizerType] = Ellipsis[源代码]
class pyqpanda.pyQPanda.OriginCMem[源代码]

origin quantum cmem

Allocate_CBit() CBit[源代码]
Allocate_CBit(cbit_num: int) CBit
Free_CBit(cbit: CBit) None[源代码]
cAlloc() CBit[源代码]
cAlloc(cbit_num: int) CBit
cAlloc_many(count: int) List[ClassicalCondition][源代码]
cFree(classical_cond: ClassicalCondition) None[源代码]
cFree_all(classical_cond_list: List[ClassicalCondition]) None[源代码]
cFree_all() None
clearAll() None[源代码]
getIdleMem() int[源代码]
getMaxMem() int[源代码]
get_allocate_cbits() List[ClassicalCondition][源代码]

Get allocate cbits

get_capacity() int[源代码]
get_cbit_by_addr(cbit_addr: int) CBit[源代码]
set_capacity(arg0: int) None[源代码]
class pyqpanda.pyQPanda.OriginCollection[源代码]
class pyqpanda.pyQPanda.OriginCollection(file_name: str)
class pyqpanda.pyQPanda.OriginCollection(arg0: OriginCollection)

A relatively free data collection class for saving data

getFilePath() str[源代码]

Get file path

getJsonString() str[源代码]

Get Json String

getKeyVector() List[str][源代码]

Get key vector

getValue(key_name: str) List[str][源代码]

Get value by Key name

getValueByKey(key_value: str) str[源代码]
getValueByKey(key_value: int) str

Get Value by key value

insertValue(key: str, *args) None[源代码]
open(file_name: str) bool[源代码]

Read the json file of the specified path

setNames(*args) None[源代码]
write() bool[源代码]

write json file

class pyqpanda.pyQPanda.OriginQubitPool[源代码]

quantum qubit pool

allocateQubitThroughPhyAddress(qubit_addr: int) Qubit[源代码]
allocateQubitThroughVirAddress(qubit_num: int) Qubit[源代码]
clearAll() None[源代码]
getIdleQubit() int[源代码]
getMaxQubit() int[源代码]
getPhysicalQubitAddr(qubit: Qubit) int[源代码]
getVirtualQubitAddress(qubit: Qubit) int[源代码]
get_allocate_qubits() QVec[源代码]

get allocate qubits

get_capacity() int[源代码]
get_max_usedqubit_addr() int[源代码]
get_qubit_by_addr(qubit_addr: int) Qubit[源代码]
qAlloc() Qubit[源代码]
qAlloc_many(qubit_num: int) List[Qubit][源代码]

Allocate a list of qubits

qFree(arg0: Qubit) None[源代码]
qFree_all(arg0: QVec) None[源代码]
qFree_all() None
set_capacity(arg0: int) None[源代码]
class pyqpanda.pyQPanda.PartialAmpQVM[源代码]

Bases: QuantumMachine

quantum partial amplitude machine class

get_prob_dict(arg0: QVec) Dict[str, float][源代码]

Get pmeasure result as dict

Args:

qubit_list: pmeasure qubits list

Returns:

measure result of quantum machine

Raises:

run_fail: An error occurred in get_prob_dict

init_qvm(backend_type: int = 0) None[源代码]
pmeasure_bin_index(bin_index: str) complex[源代码]

pmeasure bin index quantum state amplitude

Args:

string : bin string

Returns:

complex : bin amplitude

Raises:

run_fail: An error occurred in pmeasure_bin_index

pmeasure_dec_index(dec_index: str) complex[源代码]

pmeasure dec index quantum state amplitude

Args:

string : dec string

Returns:

complex : dec amplitude

Raises:

run_fail: An error occurred in pmeasure_dec_index

pmeasure_subset(index_list: List[str]) Dict[str, complex][源代码]

pmeasure quantum state amplitude subset

Args:

list : dec state string list

Returns:

list : dec amplitude result list

Raises:

run_fail: An error occurred in pmeasure_dec_index

prob_run_dict(arg0: QProg, arg1: QVec) Dict[str, float][源代码]

Run quantum program and get pmeasure result as dict

Args:

qprog: quantum program qubit_list: pmeasure qubits list

Returns:

measure result of quantum machine

Raises:

run_fail: An error occurred in measure quantum program

run(qprog: QProg, noise_model: Noise = NoiseModel()) None[源代码]
run(qprog: QCircuit, noise_model: Noise = NoiseModel()) None

run the quantum program

Args:

QProg: quantum prog size_t : NoiseModel

Returns:

none

Raises:

run_fail: An error occurred in run

class pyqpanda.pyQPanda.PhysicalQubit(*args, **kwargs)[源代码]

Physical Qubit abstract class

getQubitAddr() int[源代码]
class pyqpanda.pyQPanda.PilotNoiseParams(*args, **kwargs)[源代码]

pliot noise simulate params

double_gate_param: float[源代码]
double_p2: float[源代码]
double_pgate: float[源代码]
noise_model: str[源代码]
single_gate_param: float[源代码]
single_p2: float[源代码]
single_pgate: float[源代码]
class pyqpanda.pyQPanda.ProgCount[源代码]
double_gate_layer_num: int[源代码]
double_gate_num: int[源代码]
gate_num: int[源代码]
layer_num: int[源代码]
multi_control_gate_num: int[源代码]
node_num: int[源代码]
selected_gate_nums: Dict[GateType, int][源代码]
single_gate_layer_num: int[源代码]
single_gate_num: int[源代码]
class pyqpanda.pyQPanda.QCircuit[源代码]
class pyqpanda.pyQPanda.QCircuit(arg0: NodeIter)

quantum circuit node

begin() NodeIter[源代码]
control(control_qubits: QVec) QCircuit[源代码]
dagger() QCircuit[源代码]
end() NodeIter[源代码]
head() NodeIter[源代码]
insert(arg0: QCircuit) QCircuit[源代码]
insert(arg0: QGate) QCircuit
is_empty() bool[源代码]
last() NodeIter[源代码]
set_control(control_qubits: QVec) None[源代码]
set_dagger(arg0: bool) None[源代码]
class pyqpanda.pyQPanda.QCircuitOPtimizerMode(value: int)[源代码]

Quantum circuit optimize mode

Members:

Merge_H_X

Merge_U3

Merge_RX

Merge_RY

Merge_RZ

property name: str[源代码]
property value: int[源代码]
Merge_H_X: ClassVar[QCircuitOPtimizerMode] = Ellipsis[源代码]
Merge_RX: ClassVar[QCircuitOPtimizerMode] = Ellipsis[源代码]
Merge_RY: ClassVar[QCircuitOPtimizerMode] = Ellipsis[源代码]
Merge_RZ: ClassVar[QCircuitOPtimizerMode] = Ellipsis[源代码]
Merge_U3: ClassVar[QCircuitOPtimizerMode] = Ellipsis[源代码]
class pyqpanda.pyQPanda.QCloudService[源代码]

Bases: QuantumMachine

origin quantum cloud machine

batch_compute_url: str[源代码]
batch_inquire_url: str[源代码]
big_data_batch_compute_url: str[源代码]
compute_url: str[源代码]
configuration_header_data: str[源代码]
estimate_url: str[源代码]
inquire_url: str[源代码]
measure_qubits_num: List[int][源代码]
pqc_batch_compute_url: str[源代码]
pqc_batch_inquire_url: str[源代码]
pqc_compute_url: str[源代码]
pqc_init_url: str[源代码]
pqc_inquire_url: str[源代码]
pqc_keys_url: str[源代码]
use_compress_data: bool[源代码]
user_token: str[源代码]
batch_cyclic_query(arg0: str) Tuple[bool, List[str]][源代码]
build_error_mitigation(shots: int, chip_id: int, expectations: List[str], noise_strength: List[float], qemMethod: em_method) str[源代码]
build_full_amplitude_measure(shots: int) str[源代码]
build_full_amplitude_pmeasure(qubit_vec: List[int]) str[源代码]
build_get_expectation(hamiltonian: List[Tuple[Dict[int, str], float]], qubits: List[int]) str[源代码]
build_get_state_fidelity(shot: int, chip_id: int = 2, is_amend: bool = True, is_mapping: bool = True, is_optimization: bool = True) str[源代码]
build_get_state_tomography_density(shot: int, chip_id: int = 2, is_amend: bool = True, is_mapping: bool = True, is_optimization: bool = True) str[源代码]
build_init_object(arg0: QProg, arg1: str, arg2: int) None[源代码]
build_init_object(arg0: str, arg1: str, arg2: int) None
build_noise_measure(shots: int) str[源代码]
build_partial_amplitude_pmeasure(amplitudes: List[str]) str[源代码]
build_read_out_mitigation(shots: int, chip_id: int, expectations: List[str], noise_strength: List[float], qem_method: em_method) str[源代码]
build_real_chip_measure(shots: int, chip_id: int = 2, is_amend: bool = True, is_mapping: bool = True, is_optimization: bool = True) str[源代码]
build_real_chip_measure_batch(prog_list: List[str], shots: int, chip_id: int = 2, is_amend: bool = True, is_mapping: bool = True, is_optimization: bool = True, enable_compress_check: bool = False, batch_id: str = '', task_from: int = 4) str[源代码]
build_real_chip_measure_batch(prog_list: List[QProg], shots: int, chip_id: int = 2, is_amend: bool = True, is_mapping: bool = True, is_optimization: bool = True, enable_compress_check: bool = False, batch_id: str = '', task_from: int = 4) str
build_single_amplitude_pmeasure(amplitude: str) str[源代码]
cyclic_query(arg0: str) Tuple[bool, str][源代码]
init(user_token: str, is_logged: bool = False) None[源代码]
parse_get_task_id(arg0: str) str[源代码]
query_comolex_result(arg0: str) complex[源代码]
query_prob_dict_result(arg0: str) Dict[str, float][源代码]
query_prob_dict_result_batch(arg0: List[str]) List[Dict[str, float]][源代码]
query_prob_result(arg0: str) float[源代码]
query_prob_vec_result(arg0: str) List[float][源代码]
query_qst_result(arg0: str) List[List[complex]][源代码]
query_state_dict_result(arg0: str) Dict[str, complex][源代码]
set_noise_model(arg0: NoiseModel, arg1: List[float], arg2: List[float]) None[源代码]
set_qcloud_url(cloud_url: str) None[源代码]
class pyqpanda.pyQPanda.QCloudTaskConfig[源代码]
chip_id: real_chip_type[源代码]
cloud_token: str[源代码]
open_amend: bool[源代码]
open_mapping: bool[源代码]
open_optimization: bool[源代码]
shots: int[源代码]
class pyqpanda.pyQPanda.QError(value: int)[源代码]

Quantum QError Type

Members:

UndefineError

qErrorNone

qParameterError

qubitError

loadFileError

initStateError

destroyStateError

setComputeUnitError

runProgramError

getResultError

getQStateError

property name: str[源代码]
property value: int[源代码]
UndefineError: ClassVar[QError] = Ellipsis[源代码]
destroyStateError: ClassVar[QError] = Ellipsis[源代码]
getQStateError: ClassVar[QError] = Ellipsis[源代码]
getResultError: ClassVar[QError] = Ellipsis[源代码]
initStateError: ClassVar[QError] = Ellipsis[源代码]
loadFileError: ClassVar[QError] = Ellipsis[源代码]
qErrorNone: ClassVar[QError] = Ellipsis[源代码]
qParameterError: ClassVar[QError] = Ellipsis[源代码]
qubitError: ClassVar[QError] = Ellipsis[源代码]
runProgramError: ClassVar[QError] = Ellipsis[源代码]
setComputeUnitError: ClassVar[QError] = Ellipsis[源代码]
class pyqpanda.pyQPanda.QGate(arg0: NodeIter)[源代码]

quantum gate node

control(control_qubits: QVec) QGate[源代码]

Get a control quantumgate base on current quantum gate node

dagger() QGate[源代码]
gate_matrix() List[complex][源代码]
gate_type() int[源代码]
get_control_qubit_num() int[源代码]
get_control_qubits(control_qubits: QVec) int[源代码]

Get control vector fron current quantum gate node

Args:

qvec: control qubits output

Returns:

int: size of control qubits

get_qubits(qubits: QVec) int[源代码]

Get qubit vector inside this quantum gate

Args:

qvec: qubits output

Returns:

int: size of qubits

get_target_qubit_num() int[源代码]
is_dagger() bool[源代码]
set_control(arg0: QVec) bool[源代码]
set_dagger(arg0: bool) bool[源代码]
class pyqpanda.pyQPanda.QITE[源代码]

quantum imaginary time evolution

exec(is_optimization: bool = True) int[源代码]
get_all_exec_result(reverse: bool = False, sort: bool = False) List[List[Tuple[int, float]]][源代码]
get_ansatz_list(*args, **kwargs) Any[源代码]
get_ansatz_theta_list() List[List[float]][源代码]
get_arbitary_cofficient(arg0: float) None[源代码]
get_exec_result(reverse: bool = False, sort: bool = False) List[Tuple[int, float]][源代码]
get_result() List[Tuple[int, float]][源代码]
set_Hamiltonian(arg0) None[源代码]
set_ansatz_gate(arg0) None[源代码]
set_convergence_factor_Q(arg0: float) None[源代码]
set_delta_tau(arg0: float) None[源代码]
set_iter_num(arg0: int) None[源代码]
set_log_file(arg0: str) None[源代码]
set_para_update_mode(arg0: UpdateMode) None[源代码]
set_pauli_matrix(arg0: QuantumMachine, arg1: numpy.ndarray[numpy.float64[m, n]]) None[源代码]
set_quantum_machine_type(arg0: QMachineType) None[源代码]
set_upthrow_num(arg0: int) None[源代码]
class pyqpanda.pyQPanda.QIfProg(arg0: NodeIter)[源代码]
class pyqpanda.pyQPanda.QIfProg(classical_cond: ClassicalCondition, true_branch_qprog: QProg)
class pyqpanda.pyQPanda.QIfProg(classical_cond: ClassicalCondition, true_branch_qprog: QProg, false_branch_qprog: QProg)

quantum if prog node

get_classical_condition() ClassicalCondition[源代码]
get_false_branch() QProg[源代码]
get_true_branch() QProg[源代码]
class pyqpanda.pyQPanda.QMachineType(value: int)[源代码]

Quantum machine type

Members:

CPU

GPU

CPU_SINGLE_THREAD

NOISE

property name: str[源代码]
property value: int[源代码]
CPU: ClassVar[QMachineType] = Ellipsis[源代码]
CPU_SINGLE_THREAD: ClassVar[QMachineType] = Ellipsis[源代码]
GPU: ClassVar[QMachineType] = Ellipsis[源代码]
NOISE: ClassVar[QMachineType] = Ellipsis[源代码]
class pyqpanda.pyQPanda.QMeasure(arg0: NodeIter)[源代码]

quantum measure node

class pyqpanda.pyQPanda.QOperator[源代码]
class pyqpanda.pyQPanda.QOperator(arg0: QGate)
class pyqpanda.pyQPanda.QOperator(arg0: QCircuit)

quantum operator class

get_matrix() List[complex][源代码]
to_instruction(arg0: str) str[源代码]
class pyqpanda.pyQPanda.QOptimizationResult(arg0: str, arg1: int, arg2: int, arg3: str, arg4: float, arg5: List[float])[源代码]

quantum QOptimizationResult class

fcalls: int[源代码]
fun_val: float[源代码]
iters: int[源代码]
key: str[源代码]
message: str[源代码]
para: List[float][源代码]
class pyqpanda.pyQPanda.QPilotMachine[源代码]

pliot machine

build_noise_params(nose_model_type: int, single_params: List[float], double_params: List[float]) PilotNoiseParams[源代码]
execute_callback_full_amplitude_expectation(prog_str: str, hamiltonian: List[Tuple[Dict[int, str], float]], qubit_vec: List[int], cb_func: Callable[[ErrorCode, float], None], chip_id: int = 33554433) ErrorCode[源代码]
execute_callback_full_amplitude_measure_task(prog_str: str, cb_func: Callable[[ErrorCode, Dict[str, float]], None], chip_id: int = 33554433, shots: int = 1000) ErrorCode[源代码]
execute_callback_full_amplitude_pmeasure_task(prog_str: str, qubit_vec: List[int], cb_func: Callable[[ErrorCode, Dict[str, float]], None], chip_id: int = 33554433) ErrorCode[源代码]
execute_callback_measure_task(prog_str: str, cb_func: Callable[[ErrorCode, Dict[str, float]], None], chip_id: int = 33554432, b_mapping: bool = True, b_optimization: bool = True, shots: int = 1000, specified_block: List[int] = []) ErrorCode[源代码]
execute_callback_noise_measure_task(prog_str: str, noise_params: PilotNoiseParams, cb_func: Callable[[ErrorCode, Dict[str, float]], None], chip_id: int = 33554433, shots: int = 1000) ErrorCode[源代码]
execute_callback_partial_amplitude_task(prog_str: str, target_amplitude_vec: List[str], cb_func: Callable[[ErrorCode, Dict[str, complex]], None], chip_id: int = 33554433) ErrorCode[源代码]
execute_callback_single_amplitude_task(prog_str: str, target_amplitude: str, cb_func: Callable[[ErrorCode, complex], None], chip_id: int = 33554433) ErrorCode[源代码]
execute_full_amplitude_expectation(prog_str: str, hamiltonian: List[Tuple[Dict[int, str], float]], qubit_vec: List[int], chip_id: int = 33554433) float[源代码]
execute_full_amplitude_measure_task(prog_str: str, chip_id: int = 33554433, shots: int = 1000) Dict[str, float][源代码]
execute_full_amplitude_pmeasure_task(prog_str: str, qubit_vec: List[int], chip_id: int = 33554433) Dict[str, float][源代码]
execute_measure_task(prog_str: str, chip_id: int = 33554432, b_mapping: bool = True, b_optimization: bool = True, shots: int = 1000, specified_block: List[int] = []) List[Dict[str, float]][源代码]
execute_noise_measure_task(prog_str: str, noise_params: PilotNoiseParams, chip_id: int = 33554433, shots: int = 1000) Dict[str, float][源代码]
execute_partial_amplitude_task(prog_str: str, target_amplitude_vec: List[str], chip_id: int = 33554433) Dict[str, complex][源代码]
execute_single_amplitude_task(prog_str: str, target_amplitude: str, chip_id: int = 33554433) complex[源代码]
init(pilot_url: str, log_cout: bool = False) bool[源代码]
init_withconfig(config_path: str = 'pilotmachine.conf') bool[源代码]
class pyqpanda.pyQPanda.QPilotOSService(machine_type: str = 'CPU')[源代码]

Bases: QuantumMachine

origin quantum pilot OS Machine

async_em_compute(parameter_json: str) str[源代码]
async_real_chip_expectation(prog: QProg, hamiltonian: str, qubits: List[int] = [], shot: int = 1000, chip_id: int = 33554432, is_amend: bool = True, is_mapping: bool = True, is_optimization: bool = True, specified_block: List[int] = [], describe: str = '') str[源代码]
async_real_chip_measure(prog: QProg, shot: int = 1000, chip_id: int = 33554432, is_amend: bool = True, is_mapping: bool = True, is_optimization: bool = True, specified_block: List[int] = [], is_prob_counts: bool = True, describe: str = '') str[源代码]
async_real_chip_measure(ir: str, shot: int = 1000, chip_id: int = 33554432, is_amend: bool = True, is_mapping: bool = True, is_optimization: bool = True, specified_block: List[int] = [], is_prob_counts: bool = True, describe: str = '') str
async_real_chip_measure(prog: List[QProg], shot: int = 1000, chip_id: int = 33554432, is_amend: bool = True, is_mapping: bool = True, is_optimization: bool = True, specified_block: List[int] = [], is_prob_counts: bool = True, describe: str = '') str
async_real_chip_measure(ir: List[str], shot: int = 1000, chip_id: int = 33554432, is_amend: bool = True, is_mapping: bool = True, is_optimization: bool = True, specified_block: List[int] = [], is_prob_counts: bool = True, describe: str = '') str
async_real_chip_measure(prog: List[QProg], config_str: str) str
async_real_chip_measure_vec(prog: List[QProg], shot: int = 1000, chip_id: int = 33554432, is_amend: bool = True, is_mapping: bool = True, is_optimization: bool = True, specified_block: List[int] = [], is_prob_counts: bool = True, describe: str = '') str[源代码]
async_real_chip_measure_vec(ir: List[str], shot: int = 1000, chip_id: int = 33554432, is_amend: bool = True, is_mapping: bool = True, is_optimization: bool = True, specified_block: List[int] = [], is_prob_counts: bool = True, describe: str = '') str
async_real_chip_qst(prog: QProg, shot: int = 1000, chip_id: int = 33554432, is_amend: bool = True, is_mapping: bool = True, is_optimization: bool = True, specified_block: List[int] = [], describe: str = '') str[源代码]
async_real_chip_qst_density(prog: QProg, shot: int = 1000, chip_id: int = 33554432, is_amend: bool = True, is_mapping: bool = True, is_optimization: bool = True, specified_block: List[int] = [], describe: str = '') str[源代码]
async_real_chip_qst_fidelity(prog: QProg, shot: int = 1000, chip_id: int = 33554432, is_amend: bool = True, is_mapping: bool = True, is_optimization: bool = True, specified_block: List[int] = [], describe: str = '') str[源代码]
build_init_msg(api_key: str) str[源代码]
build_query_msg(task_id: str) str[源代码]
build_task_msg(prog: List[QProg], shot: int, chip_id: int, is_amend: bool, is_mapping: bool, is_optimization: bool, specified_block: List[int], task_describe: str) str[源代码]
cAlloc() ClassicalCondition[源代码]
cAlloc(cbit: int) ClassicalCondition

Allocate a cbit

cAlloc_many(cbit_num: int) List[ClassicalCondition][源代码]

Allocate a list of cbits

cFree(arg0: ClassicalCondition) None[源代码]

Free a cbit

cFree_all(cbit_list: List[ClassicalCondition]) None[源代码]
cFree_all() None

Free all of cbits

em_compute(parameter_json: str) List[float][源代码]
finalize() None[源代码]

finalize

get_expectation_result(task_id: str) list[源代码]
get_measure_result(task_id: str) list[源代码]
get_measure_result(task_id: str) list
get_qst_density_result(task_id: str) list[源代码]
get_qst_fidelity_result(task_id: str) list[源代码]
get_qst_result(task_id: str) list[源代码]
get_token(rep_json: str) ErrorCode[源代码]
init() None[源代码]
init(url: str, log_cout: bool = False, api_key: str = None) None
init(url: str, log_cout: bool = False, username: str = None, password: str = None) None
init_config(url: str, log_cout: bool) None[源代码]
noise_learning(parameter_json: str = True) str[源代码]
output_version() str[源代码]
pMeasureBinindex(prog: QProg, index: str, backendID: int = 33554433) float[源代码]
pMeasureDecindex(prog: QProg, index: str, backendID: int = 33554433) float[源代码]
parse_prob_counts_result(result_str: List[str]) List[Dict[str, int]][源代码]

Parse result str to map<string, double> Args:

result_str: Taeget result string

Returns:

array: vector<map<string, double>>

Raises:

none

parse_probability_result(result_str: List[str]) List[Dict[str, float]][源代码]

Parse result str to map<string, double> Args:

result_str: Taeget result string

Returns:

array: vector<map<string, double>>

Raises:

none

parse_task_result(result_str: str) Dict[str, float][源代码]

Parse result str to map<string, double> Args:

result_str: Taeget result string

Returns:

dict: map<string, double>

Raises:

none

parser_sync_result(json_str: str) list[源代码]
pmeasure_subset(prog: QProg, amplitude: List[str], backendID: int = 33554433) Dict[str, complex][源代码]
probRunDict(prog: QProg, qubit_vec: List[int], backendID: int = 33554433) Dict[str, float][源代码]
qAlloc() Qubit[源代码]

Allocate a qubit

qAlloc_many(qubit_num: int) List[Qubit][源代码]

Allocate a list of qubits

qFree(qubit: Qubit) None[源代码]

Free a qubit

qFree_all(qubit_list: QVec) None[源代码]
qFree_all(arg0: QVec) None

Free all of qubits

query_compile_prog(task_id: str, without_compensate: bool = True) list[源代码]

Query Task compile prog by task_id Args:

without_compensate: whether return the prog without angle compensate

Returns:

bool: whether find compile prog success

Raises:

none

query_task_state(task_id: str) list[源代码]
query_task_state(task_id: str, is_save: bool, file_path: str = '') list
query_task_state_vec(task_id: str) list[源代码]

Query Task State by task_id Args:

task_id: Taeget task id, got by async_real_chip_measure

Returns:

string: task state: 2: Running; 3: Finished; 4: Failed array: task result array

Raises:

none

real_chip_expectation(prog: QProg, hamiltonian: str, qubits: List[int] = [], shot: int = 1000, chip_id: int = 33554432, is_amend: bool = True, is_mapping: bool = True, is_optimization: bool = True, specified_block: List[int] = [], describe: str = '') float[源代码]
real_chip_measure(prog: QProg, shot: int = 1000, chip_id: int = 33554432, is_amend: bool = True, is_mapping: bool = True, is_optimization: bool = True, specified_block: List[int] = [], describe: str = '') Dict[str, float][源代码]
real_chip_measure(ir: str, shot: int = 1000, chip_id: int = 33554432, is_amend: bool = True, is_mapping: bool = True, is_optimization: bool = True, specified_block: List[int] = [], describe: str = '') Dict[str, float]
real_chip_measure(prog: List[QProg], shot: int = 1000, chip_id: int = 33554432, is_amend: bool = True, is_mapping: bool = True, is_optimization: bool = True, specified_block: List[int] = [], describe: str = '') List[Dict[str, float]]
real_chip_measure(ir: List[str], shot: int = 1000, chip_id: int = 33554432, is_amend: bool = True, is_mapping: bool = True, is_optimization: bool = True, specified_block: List[int] = [], describe: str = '') List[Dict[str, float]]
real_chip_measure(prog: List[QProg], config_str: str) str
real_chip_measure_prob_count(ir: str, shot: int = 1000, chip_id: int = 33554432, is_mapping: bool = True, is_optimization: bool = True, specified_block: List[int] = [], describe: str = '') Dict[str, int][源代码]
real_chip_measure_prob_count(prog: QProg, shot: int = 1000, chip_id: int = 33554432, is_mapping: bool = True, is_optimization: bool = True, specified_block: List[int] = [], describe: str = '') Dict[str, int]
real_chip_measure_prob_count(ir: List[str], shot: int = 1000, chip_id: int = 33554432, is_mapping: bool = True, is_optimization: bool = True, specified_block: List[int] = [], describe: str = '') List[Dict[str, int]]
real_chip_measure_prob_count(prog: List[QProg], shot: int = 1000, chip_id: int = 33554432, is_mapping: bool = True, is_optimization: bool = True, specified_block: List[int] = [], describe: str = '') List[Dict[str, int]]
real_chip_measure_vec(prog: List[QProg], shot: int = 1000, chip_id: int = 33554432, is_amend: bool = True, is_mapping: bool = True, is_optimization: bool = True, specified_block: List[int] = [], describe: str = '') List[Dict[str, float]][源代码]
real_chip_measure_vec(ir: List[str], shot: int = 1000, chip_id: int = 33554432, is_amend: bool = True, is_mapping: bool = True, is_optimization: bool = True, specified_block: List[int] = [], describe: str = '') List[Dict[str, float]]
runWithConfiguration(prog: QProg, shots: int = 1000, backend_id: int = 33554433, noise_model: Noise = ...) Dict[str, int][源代码]
set_config(max_qubit: int, max_cbit: int) None[源代码]

set QVM max qubit and max cbit

Args:

max_qubit: quantum machine max qubit num max_cbit: quantum machine max cbit num

Returns:

none

Raises:

run_fail: An error occurred in set_configure

tcp_recv(ip: str, port: int, task_id: str) list[源代码]
class pyqpanda.pyQPanda.QProg[源代码]
class pyqpanda.pyQPanda.QProg(arg0: QProg)
class pyqpanda.pyQPanda.QProg(arg0: QCircuit)
class pyqpanda.pyQPanda.QProg(arg0: QIfProg)
class pyqpanda.pyQPanda.QProg(arg0: QWhileProg)
class pyqpanda.pyQPanda.QProg(arg0: QGate)
class pyqpanda.pyQPanda.QProg(arg0: QMeasure)
class pyqpanda.pyQPanda.QProg(arg0: QReset)
class pyqpanda.pyQPanda.QProg(arg0: ClassicalCondition)
class pyqpanda.pyQPanda.QProg(arg0: NodeIter)

Quantum program,can construct quantum circuit,data struct is linked list

begin() NodeIter[源代码]
end() NodeIter[源代码]
get_max_qubit_addr() int[源代码]
get_qgate_num() int[源代码]
get_used_cbits(cbit_vector: List[ClassicalCondition]) List[ClassicalCondition][源代码]

get a list cbits of prog

get_used_qubits(qubit_vector: QVec) QVec[源代码]

get a list qubits of prog

head() NodeIter[源代码]
insert(arg0: QProg) QProg[源代码]
insert(arg0: QGate) QProg
insert(arg0: QCircuit) QProg
insert(arg0: QIfProg) QProg
insert(arg0: QWhileProg) QProg
insert(arg0: QMeasure) QProg
insert(arg0: QReset) QProg
insert(arg0: ClassicalCondition) QProg
is_empty() bool[源代码]
is_measure_last_pos() bool[源代码]
last() NodeIter[源代码]
class pyqpanda.pyQPanda.QProgDAG[源代码]

quantum prog dag class

get_edges() List[QProgDAGEdge][源代码]
get_target_vertex(vertice_num: int) QProgDAGVertex[源代码]
get_vertex_set() List[QProgDAGVertex][源代码]
class pyqpanda.pyQPanda.QProgDAGEdge(from_arg: int, to_arg: int, qubit_arg: int)[源代码]

quantum prog dag edge

m_from: int[源代码]
m_qubit: int[源代码]
m_to: int[源代码]
class pyqpanda.pyQPanda.QProgDAGVertex[源代码]

quantum prog dag vertex node

m_id: int[源代码]
m_layer: int[源代码]
m_pre_node: List[int][源代码]
m_succ_node: List[int][源代码]
m_type: DAGNodeType[源代码]
get_control_vec() QVec[源代码]
get_iter() NodeIter[源代码]
get_qubits_vec() QVec[源代码]
is_dagger() bool[源代码]
class pyqpanda.pyQPanda.QReset(arg0: NodeIter)[源代码]

quantum reset node

class pyqpanda.pyQPanda.QResult(*args, **kwargs)[源代码]

QResult abstract class, this class contains the result of the quantum measurement

getResultMap() Dict[str, bool][源代码]
class pyqpanda.pyQPanda.QVec[源代码]
class pyqpanda.pyQPanda.QVec(qubit_list: List[Qubit])
class pyqpanda.pyQPanda.QVec(qvec: QVec)
class pyqpanda.pyQPanda.QVec(qubit: Qubit)

Qubit vector basic class

append(qubit: Qubit) None[源代码]
pop() None[源代码]
to_list() List[Qubit][源代码]
class pyqpanda.pyQPanda.QWhileProg(arg0: NodeIter)[源代码]
class pyqpanda.pyQPanda.QWhileProg(arg0: ClassicalCondition, arg1: QProg)

quantum while node

get_classical_condition() ClassicalCondition[源代码]
get_true_branch() QProg[源代码]
class pyqpanda.pyQPanda.QuantumMachine(*args, **kwargs)[源代码]

quantum machine base class

allocate_qubit_through_phy_address(address: int) Qubit[源代码]

allocate qubits through phy address

Args:

address: qubit phy address

Returns:

Qubit

Raises:

run_fail: An error occurred in allocated qubits of QuantumMachine

allocate_qubit_through_vir_address(address: int) Qubit[源代码]

allocate qubits through vir address

Args:

address: qubit vir address

Returns:

Qubit

Raises:

run_fail: An error occurred in allocated qubits of QuantumMachine

async_run(qprog: QProg, noise_model: Noise = NoiseModel()) None[源代码]

Run quantum prog asynchronously at background Use get_processed_qgate_num() to get check the asynchronous process progress Use is_async_finished() check whether asynchronous process finished Use get_async_result() block current code and get asynchronous process result unitll it finished

cAlloc() ClassicalCondition[源代码]
cAlloc(cbit: int) ClassicalCondition

Allocate a CBit After init()

Args:

cbit_addr: cbit address, should in [0,29)

Returns:

classic result cbit

cAlloc_many(cbit_num: int) List[ClassicalCondition][源代码]

Allocate several CBits After init()

Args:

cbit_num: numbers of cbit want to be created

Returns:

list of cbit

cFree(arg0: ClassicalCondition) None[源代码]

Free a CBit

Args:

CBit: a CBit

Returns:

none

cFree_all(cbit_list: List[ClassicalCondition]) None[源代码]
cFree_all() None

Free all cbits

Args:

none

Returns:

none

directly_run(qprog: QProg, noise_model: Noise = NoiseModel()) Dict[str, bool][源代码]

Directly run quantum prog After init()

Args:

qprog: quantum program noise_model: noise model, default is no noise. noise model only work on CPUQVM now

Returns:
Dict[str, bool]: result of quantum program execution one shot.

first is the final qubit register state, second is it's measure probability

finalize() None[源代码]

finalize quantum machine

Args:

none

Returns:

none

Raises:

run_fail: An error occurred in finalize

getAllocateCMem() int[源代码]

Get allocated cbits of QuantumMachine

Args:

none

Returns:

cbit list

Raises:

run_fail: An error occurred in allocated cbits of QuantumMachine

getAllocateQubitNum() int[源代码]

Get allocated qubits of QuantumMachine

Args:

none

Returns:

qubit list

Raises:

run_fail: An error occurred in allocated qubits of QuantumMachine

getStatus(*args, **kwargs) Any[源代码]

Get the status of the Quantum machine

Args:

none

Returns:

the status of the Quantum machine, see QMachineStatus

Raises:

init_fail: An error occurred

get_allocate_cbits() List[ClassicalCondition][源代码]

Get allocated cbits of QuantumMachine

Args:

none

Returns:

cbit list

Raises:

run_fail: An error occurred in allocated cbits of QuantumMachine

get_allocate_cmem_num() int[源代码]

Get allocated cbits of QuantumMachine

Args:

none

Returns:

cbit list

Raises:

run_fail: An error occurred in allocated cbits of QuantumMachine

get_allocate_qubit_num() int[源代码]

Get allocated qubits of QuantumMachine

Args:

none

Returns:

qubit list

Raises:

run_fail: An error occurred in allocated qubits of QuantumMachine

get_allocate_qubits() QVec[源代码]

Get allocated qubits of QuantumMachine

Args:

none

Returns:

qubit list

Raises:

run_fail: An error occurred in allocated qubits of QuantumMachine

get_async_result() Dict[str, bool][源代码]
get_expectation(qprog: QProg, hamiltonian: List[Tuple[Dict[int, str], float]], qubit_list: QVec) float[源代码]
get_expectation(qprog: QProg, hamiltonian: List[Tuple[Dict[int, str], float]], qubit_list: QVec, shots: int) float

get expectation of current hamiltonian

Args:

qprog : quantum prog hamiltonian: selected hamiltonian qubit_list : measure qubit list shots : measure shots

Returns:

double : expectation of current hamiltonian

Raises:

run_fail: An error occurred in get_expectation

get_gate_time_map() Dict[GateType, int][源代码]
get_processed_qgate_num() int[源代码]
get_qstate() List[complex][源代码]

Get the status of the Quantum machine

Args:

none

Returns:

the status of the Quantum machine, see QMachineStatus

Raises:

init_fail: An error occurred

get_status(*args, **kwargs) Any[源代码]

Get the status of the Quantum machine

Args:

none

Returns:

the status of the Quantum machine, see QMachineStatus

Raises:

init_fail: An error occurred

initQVM() None[源代码]

Init the global unique quantum machine at background.

Args:

machine_type: quantum machine type, see pyQPanda.QMachineType

Returns:

bool: ture if initialization success

init_qvm() None[源代码]

Init the global unique quantum machine at background.

Args:

machine_type: quantum machine type, see pyQPanda.QMachineType

Returns:

bool: ture if initialization success

init_sparse_state(*args, **kwargs) Any[源代码]
init_state(state: List[complex] = QStat(), qlist: QVec = QVec()) None[源代码]
is_async_finished() bool[源代码]
qAlloc() Qubit[源代码]

Allocate a qubits After init()

Args:

qubit_addr: qubit physic address, should in [0,29)

Returns:

pyQPanda.Qubit: None, if qubit_addr error, or reached max number of allowed qubit

qAlloc_many(qubit_num: int) List[Qubit][源代码]

Allocate several qubits After init()

Args:

qubit_num: numbers of qubit want to be created

Returns:

list[pyQPanda.Qubit]: list of qubit

qFree(qubit: Qubit) None[源代码]

Free a CBit

Args:

CBit: a CBit

Returns:

none

qFree_all(qubit_list: QVec) None[源代码]
qFree_all(arg0: QVec) None

Free all qubits

Args:

none

Returns:

none

run_with_configuration(qprog: QProg, cbit_list: List[ClassicalCondition], data: dict, noise_model: Noise = NoiseModel()) Dict[str, int][源代码]
run_with_configuration(qprog: QProg, cbit_list: List[ClassicalCondition], shot: int, noise_model: Noise = NoiseModel()) Dict[str, int]
run_with_configuration(qprog: QProg, shot: int, noise_model: Noise = NoiseModel()) Dict[str, int]
run_with_configuration(qprog: QProg, cbit_list: List[int], shot: int, noise_model: Noise = NoiseModel()) Dict[str, int]

Run quantum program with configuration

Args:

program: quantum program cbit_list: classic cbits list shots: repeate run quantum program times noise_model: noise model, default is no noise. noise model only work on CPUQVM now

Returns:

result of quantum program execution in shots. first is the final qubit register state, second is it's hit shotRaises: run_fail: An error occurred in measure quantum program

set_configure(max_qubit: int, max_cbit: int) None[源代码]

set QVM max qubit and max cbit

Args:

max_qubit: quantum machine max qubit num max_cbit: quantum machine max cbit num

Returns:

none

Raises:

run_fail: An error occurred in set_configure

class pyqpanda.pyQPanda.QuantumStateTomography[源代码]

quantum state tomography class

caculate_tomography_density() List[List[complex]][源代码]

caculate tomography density

combine_qprogs(circuit: QProg, qlist: QVec) List[QProg][源代码]
combine_qprogs(circuit: QCircuit, qlist: QVec) List[QProg]
combine_qprogs(circuit: QProg, qlist: List[int]) List[QProg]
combine_qprogs(circuit: QCircuit, qlist: List[int]) List[QProg]

Return a list of quantum state tomography quantum programs.

exec(qm, shots: int) List[List[complex]][源代码]

run state tomography QProgs

set_qprog_results(qlist: int, results: List[Dict[str, float]]) None[源代码]

set combine_qprogs result

class pyqpanda.pyQPanda.Qubit(*args, **kwargs)[源代码]

Qubit abstract class

getPhysicalQubitPtr() PhysicalQubit[源代码]
get_phy_addr() int[源代码]
class pyqpanda.pyQPanda.RMSPropOptimizer(arg0: var, arg1: float, arg2: float, arg3: float)[源代码]

variational quantum RMSPropOptimizer

get_loss() float[源代码]
get_variables() List[var][源代码]
minimize(arg0: float, arg1: float, arg2: float) Optimizer[源代码]
run(arg0: List[var], arg1: int) bool[源代码]
class pyqpanda.pyQPanda.SingleAmpQVM[源代码]

Bases: QuantumMachine

quantum single amplitude machine class

get_prob_dict(arg0: QVec) Dict[str, float][源代码]
get_prob_dict(arg0: List[int]) Dict[str, float]

Get pmeasure result as dict

Args:

qubit_list: pmeasure qubits list

Returns:

measure result of quantum machineRaises: run_fail: An error occurred in get_prob_dict

get_quick_map_vertice(arg0: List[Tuple[int, int]]) None[源代码]

get quick map vertice

get_sequence(arg0: List[int], arg1: List[List[Tuple[int, bool]]]) int[源代码]

get prog sequence

pmeasure_bin_amplitude(arg0: str) complex[源代码]

pmeasure bin index quantum state amplitude

Args:

string : bin string

Returns:

complex : bin amplitude

Raises:

run_fail: An error occurred in pmeasure_bin_index

pmeasure_bin_index(arg0: str) float[源代码]

pmeasure bin index quantum state amplitude

Args:

string : bin string

Returns:

double : bin amplitude prob

Raises:

run_fail: An error occurred in pmeasure_bin_index

pmeasure_dec_amplitude(arg0: str) complex[源代码]

pmeasure dec index quantum state amplitude

Args:

string : dec string

Returns:

complex : dec amplitude amplitude

Raises:

run_fail: An error occurred in pmeasure_dec_index

pmeasure_dec_index(arg0: str) float[源代码]

pmeasure dec index quantum state amplitude

Args:

string : dec string

Returns:

double : dec amplitude prob

Raises:

run_fail: An error occurred in pmeasure_dec_index

prob_run_dict(arg0: QProg, arg1: QVec) Dict[str, float][源代码]
prob_run_dict(arg0: QProg, arg1: List[int]) Dict[str, float]

Run quantum program and get pmeasure result as dict

Args:

qprog: quantum program qubit_list: pmeasure qubits list

Returns:

measure result of quantum machine

Raises:

run_fail: An error occurred in measure quantum program

run(prog: QProg, qv: QVec, max_rank: int = 30, alloted_time: int = 5) None[源代码]
run(arg0: QProg, arg1: QVec, arg2: int, arg3: List[List[Tuple[int, bool]]]) None

run the quantum program

Args:

QProg: quantum prog QVec: qubits list size_t: max_rank list: sequences

Returns:

none

Raises:

run_fail: An error occurred in run

class pyqpanda.pyQPanda.SingleGateTransferType(value: int)[源代码]

Quantum single gate transfer type

Members:

SINGLE_GATE_INVALID

ARBITRARY_ROTATION

DOUBLE_CONTINUOUS

SINGLE_CONTINUOUS_DISCRETE

DOUBLE_DISCRETE

property name: str[源代码]
property value: int[源代码]
ARBITRARY_ROTATION: ClassVar[SingleGateTransferType] = Ellipsis[源代码]
DOUBLE_CONTINUOUS: ClassVar[SingleGateTransferType] = Ellipsis[源代码]
DOUBLE_DISCRETE: ClassVar[SingleGateTransferType] = Ellipsis[源代码]
SINGLE_CONTINUOUS_DISCRETE: ClassVar[SingleGateTransferType] = Ellipsis[源代码]
SINGLE_GATE_INVALID: ClassVar[SingleGateTransferType] = Ellipsis[源代码]
class pyqpanda.pyQPanda.SparseQVM[源代码]

Bases: QuantumMachine

quantum sparse machine class

directlyRun(arg0: QProg) Dict[str, bool][源代码]

Run quantum program and get pmeasure result as dict

Args:

qprog: quantum program

Returns:

Dict[str, bool]: result of quantum program execution one shot.

Raises:

run_fail: An error occurred in measure quantum program

directly_run(arg0: QProg) Dict[str, bool][源代码]

Run quantum program and get pmeasure result as dict

Args:

qprog: quantum program

Returns:

measure result of quantum machine

Raises:

run_fail: An error occurred in measure quantum program

init_qvm() None[源代码]

init quantum virtual machine

prob_run_dict(arg0: QProg) Dict[str, float][源代码]

Run quantum program and get pmeasure result as dict

Args:

qprog: quantum program

Returns:

measure result of quantum machine

Raises:

run_fail: An error occurred in measure quantum program

run_with_configuration(arg0: QProg, arg1: List[ClassicalCondition], arg2: int) Dict[str, int][源代码]

Run quantum program and get pmeasure result as dict

Args:

qprog: quantum program

Args:

cbits: quantum cbits

Args:

shots: samble shots

Returns:

measure result of quantum machine

Raises:

run_fail: An error occurred in measure quantum program

class pyqpanda.pyQPanda.Stabilizer[源代码]

Bases: QuantumMachine

simulator for basic clifford simulator

init_qvm() None[源代码]

init quantum virtual machine

prob_run_dict(qprog: QProg, qubits: QVec, select_max: int = -1) Dict[str, float][源代码]

Run quantum program and get probabilities

Args:

prog: quantum program qubits: pmeasure qubits

Returns:

probabilities result of quantum program

Raises:

run_fail: An error occurred in prob_run_dict

run_with_configuration(qprog: QProg, shot: int) Dict[str, int][源代码]

Run quantum program and get shots result

Args:

prog: quantum program int: measure shots

Returns:

shots result of quantum program

Raises:

run_fail: An error occurred in run_with_configuration

set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float) None[源代码]
set_noise_model(arg0: NoiseModel, arg1: List[GateType], arg2: float) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float, arg3: QVec) None
set_noise_model(arg0: NoiseModel, arg1: List[GateType], arg2: float, arg3: QVec) None
set_noise_model(arg0: NoiseModel, arg1: GateType, arg2: float, arg3: List[QVec]) None
class pyqpanda.pyQPanda.UpdateMode(value: int)[源代码]

quantum imaginary time evolution update mode

Members:

GD_VALUE

GD_DIRECTION

property name: str[源代码]
property value: int[源代码]
GD_DIRECTION: ClassVar[UpdateMode] = Ellipsis[源代码]
GD_VALUE: ClassVar[UpdateMode] = Ellipsis[源代码]
class pyqpanda.pyQPanda.VanillaGradientDescentOptimizer(arg0: var, arg1: float, arg2: float, arg3: OptimizerMode)[源代码]

variational quantum VanillaGradientDescentOptimizer

get_loss() float[源代码]
get_variables() List[var][源代码]
minimize(arg0: float, arg1: float) Optimizer[源代码]
run(arg0: List[var], arg1: int) bool[源代码]
class pyqpanda.pyQPanda.VariationalQuantumCircuit[源代码]
class pyqpanda.pyQPanda.VariationalQuantumCircuit(arg0: QCircuit)

variational quantum CIRCUIT class

control(arg0: QVec) VariationalQuantumCircuit[源代码]
dagger() VariationalQuantumCircuit[源代码]
feed() QCircuit[源代码]
feed(arg0) QCircuit
get_control_qubit() QVec[源代码]
insert(arg0: VariationalQuantumGate_I) VariationalQuantumCircuit[源代码]
insert(arg0: VariationalQuantumGate_H) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_X) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_Y) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_T) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_S) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_Z) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_X1) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_Y1) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_Z1) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_U1) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_U2) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_U3) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_U4) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_RX) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_RY) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_RZ) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_CNOT) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_CR) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_CZ) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_CRX) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_CRY) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_CRZ) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_SWAP) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_iSWAP) VariationalQuantumCircuit
insert(arg0: VariationalQuantumGate_SqiSWAP) VariationalQuantumCircuit
insert(arg0: VariationalQuantumCircuit) VariationalQuantumCircuit
insert(arg0: QCircuit) VariationalQuantumCircuit
insert(arg0: QGate) VariationalQuantumCircuit
is_dagger() bool[源代码]
set_control(arg0: QVec) bool[源代码]
set_dagger(arg0: bool) bool[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate(*args, **kwargs)[源代码]

variational quantum gate base class

feed(arg0: Dict[int, float]) QGate[源代码]
get_constants() List[float][源代码]
get_control_qubit() QVec[源代码]
get_vars() List[var][源代码]
is_dagger() bool[源代码]
set_control(arg0: QVec) bool[源代码]
set_dagger(arg0: bool) bool[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_CNOT(arg0: Qubit, arg1: Qubit)[源代码]

Bases: VariationalQuantumGate

variational quantum CNOT gate class

control(arg0: QVec) VariationalQuantumGate_CNOT[源代码]
dagger() VariationalQuantumGate_CNOT[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_CR(arg0: Qubit, arg1: Qubit, arg2: float)[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_CR(arg0: Qubit, arg1: Qubit, arg2: var)
class pyqpanda.pyQPanda.VariationalQuantumGate_CR(arg0: VariationalQuantumGate_CR)

Bases: VariationalQuantumGate

variational quantum CR gate class

control(arg0: QVec) VariationalQuantumGate_CR[源代码]
dagger() VariationalQuantumGate_CR[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_CRX(arg0: Qubit, arg1: QVec, arg2: float)[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_CRX(arg0: Qubit, arg1: QVec, arg2: var)
class pyqpanda.pyQPanda.VariationalQuantumGate_CRX(arg0: VariationalQuantumGate_CRX)

Bases: VariationalQuantumGate

variational quantum CRX gate class

control(arg0: QVec) VariationalQuantumGate_CRX[源代码]
dagger() VariationalQuantumGate_CRX[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_CRY(arg0: Qubit, arg1: QVec, arg2: float)[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_CRY(arg0: Qubit, arg1: QVec, arg2: var)
class pyqpanda.pyQPanda.VariationalQuantumGate_CRY(arg0: VariationalQuantumGate_CRY)

Bases: VariationalQuantumGate

variational quantum CRY gate class

control(arg0: QVec) VariationalQuantumGate_CRY[源代码]
dagger() VariationalQuantumGate_CRY[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_CRZ(arg0: Qubit, arg1: QVec, arg2: float)[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_CRZ(arg0: Qubit, arg1: QVec, arg2: var)
class pyqpanda.pyQPanda.VariationalQuantumGate_CRZ(arg0: VariationalQuantumGate_CRZ)

Bases: VariationalQuantumGate

variational quantum CRZ gate class

control(arg0: QVec) VariationalQuantumGate_CRZ[源代码]
dagger() VariationalQuantumGate_CRZ[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_CU(arg0: Qubit, arg1: Qubit, arg2: float, arg3: float, arg4: float, arg5: float)[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_CU(arg0: Qubit, arg1: Qubit, arg2: var, arg3: var, arg4: var, arg5: var)
class pyqpanda.pyQPanda.VariationalQuantumGate_CU(arg0: VariationalQuantumGate_CU)

Bases: VariationalQuantumGate

variational quantum CU gate class

control(arg0: QVec) VariationalQuantumGate_CU[源代码]
dagger() VariationalQuantumGate_CU[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_CZ(arg0: Qubit, arg1: Qubit)[源代码]

Bases: VariationalQuantumGate

variational quantum CZ gate class

control(arg0: QVec) VariationalQuantumGate_CZ[源代码]
dagger() VariationalQuantumGate_CZ[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_H(arg0: Qubit)[源代码]

Bases: VariationalQuantumGate

variational quantum H gate class

control(arg0: QVec) VariationalQuantumGate_H[源代码]
dagger() VariationalQuantumGate_H[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_I(arg0: Qubit)[源代码]

Bases: VariationalQuantumGate

variational quantum I gate class

control(arg0: QVec) VariationalQuantumGate_I[源代码]
dagger() VariationalQuantumGate_I[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_RX(arg0: Qubit, arg1: var)[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_RX(arg0: Qubit, arg1: float)

Bases: VariationalQuantumGate

variational quantum RX gate class

control(arg0: QVec) VariationalQuantumGate_RX[源代码]
dagger() VariationalQuantumGate_RX[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_RY(arg0: Qubit, arg1: var)[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_RY(arg0: Qubit, arg1: float)

Bases: VariationalQuantumGate

variational quantum RY gate class

control(arg0: QVec) VariationalQuantumGate_RY[源代码]
dagger() VariationalQuantumGate_RY[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_RZ(arg0: Qubit, arg1: var)[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_RZ(arg0: Qubit, arg1: float)

Bases: VariationalQuantumGate

variational quantum RZ gate class

control(arg0: QVec) VariationalQuantumGate_RZ[源代码]
dagger() VariationalQuantumGate_RZ[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_S(arg0: Qubit)[源代码]

Bases: VariationalQuantumGate

variational quantum S gate class

control(arg0: QVec) VariationalQuantumGate_S[源代码]
dagger() VariationalQuantumGate_S[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_SWAP(arg0: Qubit, arg1: Qubit)[源代码]

Bases: VariationalQuantumGate

variational quantum SWAP gate class

control(arg0: QVec) VariationalQuantumGate_SWAP[源代码]
dagger() VariationalQuantumGate_SWAP[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_SqiSWAP(arg0: Qubit, arg1: Qubit)[源代码]

Bases: VariationalQuantumGate

variational quantum SqiSWAP gate class

control(arg0: QVec) VariationalQuantumGate_SqiSWAP[源代码]
dagger() VariationalQuantumGate_SqiSWAP[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_T(arg0: Qubit)[源代码]

Bases: VariationalQuantumGate

variational quantum T gate class

control(arg0: QVec) VariationalQuantumGate_T[源代码]
dagger() VariationalQuantumGate_T[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_U1(arg0: Qubit, arg1: var)[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_U1(arg0: Qubit, arg1: float)

Bases: VariationalQuantumGate

variational quantum U1 gate class

control(arg0: QVec) VariationalQuantumGate_U1[源代码]
dagger() VariationalQuantumGate_U1[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_U2(arg0: Qubit, arg1: var, arg2: var)[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_U2(arg0: Qubit, arg1: float, arg2: float)

Bases: VariationalQuantumGate

variational quantum U2 gate class

control(arg0: QVec) VariationalQuantumGate_U2[源代码]
dagger() VariationalQuantumGate_U2[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_U3(arg0: Qubit, arg1: var, arg2: var, arg3: var)[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_U3(arg0: Qubit, arg1: float, arg2: float, arg3: float)

Bases: VariationalQuantumGate

variational quantum U3 gate class

control(arg0: QVec) VariationalQuantumGate_U3[源代码]
dagger() VariationalQuantumGate_U3[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_U4(arg0: Qubit, arg1: var, arg2: var, arg3: var, arg4: var)[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_U4(arg0: Qubit, arg1: float, arg2: float, arg3: float, arg4: float)

Bases: VariationalQuantumGate

variational quantum U4 gate class

control(arg0: QVec) VariationalQuantumGate_U4[源代码]
dagger() VariationalQuantumGate_U4[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_X(arg0: Qubit)[源代码]

Bases: VariationalQuantumGate

variational quantum X gate class

control(arg0: QVec) VariationalQuantumGate_X[源代码]
dagger() VariationalQuantumGate_X[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_X1(arg0: Qubit)[源代码]

Bases: VariationalQuantumGate

variational quantum X1 gate class

control(arg0: QVec) VariationalQuantumGate_X1[源代码]
dagger() VariationalQuantumGate_X1[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_Y(arg0: Qubit)[源代码]

Bases: VariationalQuantumGate

variational quantum Y gate class

control(arg0: QVec) VariationalQuantumGate_Y[源代码]
dagger() VariationalQuantumGate_Y[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_Y1(arg0: Qubit)[源代码]

Bases: VariationalQuantumGate

variational quantum Y1 gate class

control(arg0: QVec) VariationalQuantumGate_Y1[源代码]
dagger() VariationalQuantumGate_Y1[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_Z(arg0: Qubit)[源代码]

Bases: VariationalQuantumGate

variational quantum Z gate class

control(arg0: QVec) VariationalQuantumGate_Z[源代码]
dagger() VariationalQuantumGate_Z[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_Z1(arg0: Qubit)[源代码]

Bases: VariationalQuantumGate

variational quantum Z1 gate class

control(arg0: QVec) VariationalQuantumGate_Z1[源代码]
dagger() VariationalQuantumGate_Z1[源代码]
class pyqpanda.pyQPanda.VariationalQuantumGate_iSWAP(arg0: Qubit, arg1: Qubit)[源代码]

Bases: VariationalQuantumGate

variational quantum iSWAP gate class

control(arg0: QVec) VariationalQuantumGate_iSWAP[源代码]
dagger() VariationalQuantumGate_iSWAP[源代码]
class pyqpanda.pyQPanda.em_method(value: int)[源代码]

origin quantum real chip error_mitigation type

Members:

ZNE

PEC

READ_OUT

property name: str[源代码]
property value: int[源代码]
PEC: ClassVar[em_method] = Ellipsis[源代码]
READ_OUT: ClassVar[em_method] = Ellipsis[源代码]
ZNE: ClassVar[em_method] = Ellipsis[源代码]
class pyqpanda.pyQPanda.expression(arg0: var)[源代码]

variational quantum expression class

backprop(arg0: Dict[var, numpy.ndarray[numpy.float64[m, n]]]) None[源代码]
backprop(arg0: Dict[var, numpy.ndarray[numpy.float64[m, n]]], arg1: List[var]) None
find_leaves() List[var][源代码]
find_non_consts(arg0: List[var]) List[var][源代码]
get_root() var[源代码]
propagate() numpy.ndarray[numpy.float64[m, n]][源代码]
propagate(arg0: List[var]) numpy.ndarray[numpy.float64[m, n]]
class pyqpanda.pyQPanda.hadamard_circuit(arg0: QVec)[源代码]

Bases: QCircuit

hadamard circuit class

class pyqpanda.pyQPanda.real_chip_type(value: int)[源代码]

origin quantum real chip type enum

Members:

origin_wuyuan_d3

origin_wuyuan_d4

origin_wuyuan_d5

origin_72

property name: str[源代码]
property value: int[源代码]
origin_72: ClassVar[real_chip_type] = Ellipsis[源代码]
origin_wuyuan_d3: ClassVar[real_chip_type] = Ellipsis[源代码]
origin_wuyuan_d4: ClassVar[real_chip_type] = Ellipsis[源代码]
origin_wuyuan_d5: ClassVar[real_chip_type] = Ellipsis[源代码]
class pyqpanda.pyQPanda.var(arg0: float)[源代码]
class pyqpanda.pyQPanda.var(arg0: numpy.ndarray[numpy.float64[m, n], flags.writeable])
class pyqpanda.pyQPanda.var(arg0: float, arg1: bool)
class pyqpanda.pyQPanda.var(arg0: numpy.ndarray[numpy.float64[m, n], flags.writeable], arg1: bool)

quantum variational class

clone() var[源代码]
get_value() numpy.ndarray[numpy.float64[m, n]][源代码]
set_value(arg0: numpy.ndarray[numpy.float64[m, n]]) None[源代码]
set_value(arg0: float) None
pyqpanda.pyQPanda.BARRIER(qubit: Qubit) QGate[源代码]
pyqpanda.pyQPanda.BARRIER(qubit_list: int) QGate
pyqpanda.pyQPanda.BARRIER(qubit_list: QVec) QGate
pyqpanda.pyQPanda.BARRIER(qubit_addr_list: List[int]) QGate

Create a BARRIER gate

Args:

qubit_list : measure qubits list

Returns:

a BARRIER node

pyqpanda.pyQPanda.CNOT(control_qubit: Qubit, target_qubit: Qubit) QGate[源代码]
pyqpanda.pyQPanda.CNOT(control_qubit_list: QVec, target_qubit_list: QVec) QCircuit
pyqpanda.pyQPanda.CNOT(control_qubit_addr: int, target_qubit_addr: int) QGate
pyqpanda.pyQPanda.CNOT(control_qubit_addr_list: List[int], target_qubit_addr_list: List[int]) QCircuit
Returns:

a CNOT gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.CP(control_qubit: Qubit, target_qubit: Qubit, theta_angle: float) QGate[源代码]
pyqpanda.pyQPanda.CP(control_qubit_list: QVec, target_qubit_list: QVec, theta_angle: float) QCircuit
pyqpanda.pyQPanda.CP(control_qubit_addr: int, target_qubit_addr: int, theta_angle: float) QGate
pyqpanda.pyQPanda.CP(control_qubit_addr_list: List[int], target_qubit_addr_list: List[int], theta_angle: float) QCircuit
Returns:

a CP gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.CR(control_qubit: Qubit, target_qubit: Qubit, theta_angle: float) QGate[源代码]
pyqpanda.pyQPanda.CR(control_qubit_list: QVec, target_qubit_list: QVec, theta_angle: float) QCircuit
pyqpanda.pyQPanda.CR(control_qubit_addr: int, target_qubit_addr: int, theta_angle: float) QGate
pyqpanda.pyQPanda.CR(control_qubit_addr_list: List[int], target_qubit_addr_list: List[int], theta_angle: float) QCircuit
Returns:

a CR gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.CU(alpha_angle: float, beta_angle: float, gamma_angle: float, delta_angle: float, control_qubit: Qubit, target_qubit: Qubit) QGate[源代码]
pyqpanda.pyQPanda.CU(alpha_angle: float, beta_angle: float, gamma_angle: float, delta_angle: float, control_qubit_list: QVec, target_qubi_list: QVec) QCircuit
pyqpanda.pyQPanda.CU(matrix: List[complex], control_qubit: Qubit, target_qubit: Qubit) QGate
pyqpanda.pyQPanda.CU(matrix: List[complex], control_qubit_list: QVec, target_qubit_list: QVec) QCircuit
pyqpanda.pyQPanda.CU(control_qubit: Qubit, target_qubit: Qubit, alpha_angle: float, beta_angle: float, gamma_angle: float, delta_angle: float) QGate
pyqpanda.pyQPanda.CU(control_qubit_list: QVec, target_qubit_list: QVec, alpha_angle: float, beta_angle: float, gamma_angle: float, delta_angle: float) QCircuit
pyqpanda.pyQPanda.CU(control_qubit_addr: int, target_qubit_addr: int, alpha_angle: float, beta_angle: float, gamma_angle: float, delta_angle: float) QGate
pyqpanda.pyQPanda.CU(control_qubit_addr_list: List[int], target_qubit_addr_list: List[int], alpha_angle: float, beta_angle: float, gamma_angle: float, delta_angle: float) QCircuit
pyqpanda.pyQPanda.CU(control_qubit: Qubit, target_qubit: Qubit, matrix: List[complex]) QGate
pyqpanda.pyQPanda.CU(control_qubit_list: QVec, target_qubit_list: QVec, matrix: List[complex]) QCircuit
pyqpanda.pyQPanda.CU(control_qubit_addr: int, target_qubit_addr: int, matrix: List[complex]) QGate
pyqpanda.pyQPanda.CU(control_qubit_addr_list: List[int], target_qubit_addr_list: List[int], matrix: List[complex]) QCircuit

Create a CU gate

Args:

matrix : CU gate matrix qubit addr list: control qubit addr list qubit addr list: target qubit addr list

Returns:

a CU node

pyqpanda.pyQPanda.CZ(control_qubit: Qubit, target_qubit: Qubit) QGate[源代码]
pyqpanda.pyQPanda.CZ(control_qubit_list: QVec, target_qubit_list: QVec) QCircuit
pyqpanda.pyQPanda.CZ(control_qubit_addr: int, target_qubit_addr: int) QGate
pyqpanda.pyQPanda.CZ(control_qubit_addr_list: List[int], target_qubit_addr_list: List[int]) QCircuit
Returns:

a CZ gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.CreateEmptyCircuit() QCircuit[源代码]

Create an empty QCircuit Container

Args:

none

Returns:

a empty QCircuit

pyqpanda.pyQPanda.CreateEmptyQProg() QProg[源代码]

Create an empty QProg Container

Args:

none

Returns:

a empty QProg

pyqpanda.pyQPanda.CreateIfProg(classical_condition: ClassicalCondition, true_node: QProg) QIfProg[源代码]
pyqpanda.pyQPanda.CreateIfProg(classical_condition: ClassicalCondition, true_node: QProg, false_node: QProg) QIfProg

Create a classical quantum IfProg

Args:

classical_condition: quatum cbit true_node: quantum IfProg true qnode false_node: quantum IfProg false qnode

Returns:

a classical quantum IfProg

pyqpanda.pyQPanda.CreateWhileProg(classical_condition: ClassicalCondition, true_node: QProg) QWhileProg[源代码]

Create a WhileProg Args:

classical_condition: quatum cbit true_node: quantum QWhile qnode

Returns:

a WhileProg

pyqpanda.pyQPanda.Grover(*args, **kwargs) Any[源代码]

Quantum grover circuit

Args:

qvec: qubit list Classical_condition: quantum Classical condition QuantumMachine: quantum machine

Returns:

result : Grover circuit

Raises:

run_fail: An error occurred in Grover

pyqpanda.pyQPanda.Grover_search(list: List[str], Classical_condition: str, QuantumMachine: Grover_search.QuantumMachine, data: int = 2) Grover_search.list

use Grover algorithm to search target data, return QProg and search_result

pyqpanda.pyQPanda.H(qubit: Qubit) QGate[源代码]
pyqpanda.pyQPanda.H(qubit_list: QVec) QCircuit
pyqpanda.pyQPanda.H(qubit_addr: int) QGate
pyqpanda.pyQPanda.H(qubit_addr_list: List[int]) QCircuit

Create a H gate

Args:

qubit_list_addr: quantum gate qubits list addr

Returns:

a H gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.HHL_solve_linear_equations(matrix_A: List[complex], data_b: List[float], precision_cnt: int = 0) List[complex][源代码]

Use HHL algorithm to solve the target linear systems of equations : Ax = b

Args:

matrix_A: a unitary matrix or Hermitian N*N matrix with N = 2 ^ n data_b: a given vector precision_cnt: The count of digits after the decimal point

default is 0, indicates that there are only integer solutions.

Returns:

QStat The solution of equation, i.e.x for Ax = b

Notes:

The higher the precision is, the more qubit number and circuit - depth will be, for example: 1 - bit precision, 4 additional qubits are required, for 2 - bit precision, we need 7 additional qubits, and so on.

pyqpanda.pyQPanda.I(qubit: Qubit) QGate[源代码]
pyqpanda.pyQPanda.I(qubit_list: QVec) QCircuit
pyqpanda.pyQPanda.I(qubit_addr: int) QGate
pyqpanda.pyQPanda.I(qubit_addr_list: List[int]) QCircuit

Create a I gate

Args:

qubit_list_addr: quantum gate qubits list addr

Returns:

a I gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.MAJ(arg0: Qubit, arg1: Qubit, arg2: Qubit) QCircuit[源代码]

Quantum adder MAJ module

pyqpanda.pyQPanda.MAJ2(arg0: QVec, arg1: QVec, arg2: Qubit) QCircuit[源代码]

Quantum adder MAJ2 module

pyqpanda.pyQPanda.MS(first_qubit: Qubit, second_qubit: Qubit) QGate[源代码]
pyqpanda.pyQPanda.MS(first_qubit_list: QVec, second_qubit_list: QVec) QCircuit
pyqpanda.pyQPanda.MS(first_qubit_addr: int, second_qubit_addr: int) QGate
pyqpanda.pyQPanda.MS(first_qubit_addr_list: List[int], second_qubit_addr_list: List[int]) QCircuit
Returns:

a MS gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.Measure(qubit: Qubit, cbit: ClassicalCondition) QMeasure[源代码]
pyqpanda.pyQPanda.Measure(qubit: Qubit, cbit: CBit) QMeasure
pyqpanda.pyQPanda.Measure(qubit_addr: int, cbit_addr: int) QMeasure

Create an measure node

Args:

qubit : measure qubit cbit : cbit stores quantum measure result

Returns:

a quantum measure node

pyqpanda.pyQPanda.OBMT_mapping(prog: QProg, quantum_machine: QuantumMachine, b_optimization: bool = False, max_partial: int = 4294967295, max_children: int = 4294967295, config_data: str = 'QPandaConfig.json') QProg[源代码]
pyqpanda.pyQPanda.OBMT_mapping(prog: QProg, quantum_machine: QuantumMachine, b_optimization: bool, arch_matrix: numpy.ndarray[numpy.float64[m, n]]) QProg

OPT_BMT mapping

Args:

prog: the target prog quantum_machine: quantum machine b_optimization: whether open the optimization arch_matrix: arch graph matrix

Returns:

mapped quantum program

pyqpanda.pyQPanda.P(qubit: Qubit, angle: float) QGate[源代码]
pyqpanda.pyQPanda.P(qubit_list: QVec, angle: float) QCircuit
pyqpanda.pyQPanda.P(qubit_addr: int, angle: float) QGate
pyqpanda.pyQPanda.P(qubit_addr_list: List[int], angle: float) QCircuit

Create a P gate Args:

qubit_list_addr: quantum gate qubits list addr args : quantum gate angles

Returns:

a P gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.PMeasure(arg0: QVec, arg1: int) List[Tuple[int, float]][源代码]

Deprecated, use pmeasure instead

Args:

QVec : pmeasure qubits list select_num : result select num

Returns:

result: pmeasure qubits result

Raises:

run_fail: An error occurred in pmeasure

pyqpanda.pyQPanda.PMeasure_no_index(arg0: QVec) List[float][源代码]

Deprecated, use pmeasure_no_index instead

Args:

QVec : pmeasure qubits list

Returns:

result: pmeasure qubits result

Raises:

run_fail: An error occurred in pmeasure_no_index

pyqpanda.pyQPanda.QAdd(arg0: QVec, arg1: QVec, arg2: QVec) QCircuit[源代码]

Quantum adder that supports signed operations, but ignore carry

pyqpanda.pyQPanda.QAdder(arg0: QVec, arg1: QVec, arg2: Qubit, arg3: Qubit) QCircuit[源代码]

Quantum adder with carry

pyqpanda.pyQPanda.QAdderIgnoreCarry(arg0: QVec, arg1: QVec, arg2: Qubit) QCircuit[源代码]

Args:

QVec: qubits list a QVec: qubits list b QVec: qubits list c Qubit: qubit

Returns:

result : circuit

Raises:

run_fail: An error occurred in QAdderIgnoreCarry

pyqpanda.pyQPanda.QComplement(arg0: QVec, arg1: QVec) QCircuit[源代码]

Convert quantum state to binary complement representation

pyqpanda.pyQPanda.QDiv(arg0: QVec, arg1: QVec, arg2: QVec, arg3: QVec, arg4: ClassicalCondition) QProg[源代码]

Quantum division

pyqpanda.pyQPanda.QDivWithAccuracy(arg0: QVec, arg1: QVec, arg2: QVec, arg3: QVec, arg4: QVec, arg5: List[ClassicalCondition]) QProg[源代码]

Args:

QVec: qubits list a QVec: qubits list b QVec: qubits list c QVec: qubits list k QVec: qubits list f QVec: qubits list s list: ClassicalCondition list

Returns:

result : circuit

Raises:

run_fail: An error occurred in QDivWithAccuracy

pyqpanda.pyQPanda.QDivider(a: QVec, b: QVec, c: QVec, k: QVec, t: ClassicalCondition) QProg[源代码]

Quantum division, only supports positive division, and the highest position of a and b and c is sign bit

pyqpanda.pyQPanda.QDividerWithAccuracy(a: QVec, b: QVec, c: QVec, k: QVec, f: QVec, s: List[ClassicalCondition]) QProg[源代码]

Args:

QVec: qubits list a QVec: qubits list b QVec: qubits list c QVec: qubits list k QVec: qubits list f QVec: qubits list s list: ClassicalCondition list

Returns:

result : circuit

Raises:

run_fail: An error occurred in QDividerWithAccuracy

pyqpanda.pyQPanda.QDouble(first_qubit: Qubit, second_qubit: Qubit, matrix: List[complex]) QGate[源代码]
pyqpanda.pyQPanda.QDouble(first_qubit_list: QVec, second_qubit_list: QVec, matrix: List[complex]) QCircuit
pyqpanda.pyQPanda.QDouble(first_qubit_addr: int, second_qubit_addr: int, matrix: List[complex]) QGate
pyqpanda.pyQPanda.QDouble(first_qubit_addr_list: List[int], second_qubit_addr_list: List[int], matrix: List[complex]) QCircuit
Returns:

a QDouble gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.QFT(qubits: QVec) QCircuit[源代码]

Build QFT quantum circuit

Args:

qvec: qubit list

Returns:

result : qft circuit

Raises:

run_fail: An error occurred in QFT

pyqpanda.pyQPanda.QMul(arg0: QVec, arg1: QVec, arg2: QVec, arg3: QVec) QCircuit[源代码]

Quantum multiplication

pyqpanda.pyQPanda.QMultiplier(arg0: QVec, arg1: QVec, arg2: QVec, arg3: QVec) QCircuit[源代码]

Quantum multiplication, only supports positive multiplication

pyqpanda.pyQPanda.QOracle(qubit_list: QVec, matrix: numpy.ndarray[numpy.complex128[m, n]], tol: float = 1e-10) QGate[源代码]

Generate QOracle Gate

Args: qubit_list: gate in qubit list

matrix: gate operator matrix

Return:

Oracle gate

pyqpanda.pyQPanda.QPE(control_qubits: QVec, target_qubits: QVec, matrix: List[complex], b_estimate_eigenvalue: bool = False) QCircuit[源代码]

Quantum phase estimation

Args:

control_qubits: control qubit list target_qubits: target qubit list matrix: matrix

Returns:

result : QPE circuit

Raises:

run_fail: An error occurred in QPE

pyqpanda.pyQPanda.QSub(arg0: QVec, arg1: QVec, arg2: QVec) QCircuit[源代码]

Quantum subtraction

pyqpanda.pyQPanda.RX(qubit: Qubit, angle: float) QGate[源代码]
pyqpanda.pyQPanda.RX(qubit_list: QVec, angle: float) QCircuit
pyqpanda.pyQPanda.RX(qubit_addr: int, angle: float) QGate
pyqpanda.pyQPanda.RX(qubit_addr_list: List[int], angle: float) QCircuit

Create a RX gate Args:

qubit_list_addr: quantum gate qubits list addr args : quantum gate angles

Returns:

a RX gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.RXX(control_qubit: Qubit, target_qubit: Qubit, alpha_angle: float) QGate[源代码]
pyqpanda.pyQPanda.RXX(control_qubit_list: QVec, target_qubit_list: QVec, alpha_angle: float) QCircuit
pyqpanda.pyQPanda.RXX(control_qubit_addr: int, target_qubit_addr: int, alpha_angle: float) QGate
pyqpanda.pyQPanda.RXX(control_qubit_addr_list: List[int], target_qubit_addr_list: List[int], alpha_angle: float) QCircuit

Create a RXX gate

Args:

qubit addr list : control qubit addr list qubit addr list : target qubit addr list double: gate rotation angle theta

Returns:

a RXX gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.RY(qubit: Qubit, angle: float) QGate[源代码]
pyqpanda.pyQPanda.RY(qubit_list: QVec, angle: float) QCircuit
pyqpanda.pyQPanda.RY(qubit_addr: int, angle: float) QGate
pyqpanda.pyQPanda.RY(qubit_addr_list: List[int], angle: float) QCircuit

Create a RY gate Args:

qubit_list_addr: quantum gate qubits list addr args : quantum gate angles

Returns:

a RY gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.RYY(control_qubit: Qubit, target_qubit: Qubit, alpha_angle: float) QGate[源代码]
pyqpanda.pyQPanda.RYY(control_qubit_list: QVec, target_qubit_list: QVec, alpha_angle: float) QCircuit
pyqpanda.pyQPanda.RYY(control_qubit_addr: int, target_qubit_addr: int, alpha_angle: float) QGate
pyqpanda.pyQPanda.RYY(control_qubit_addr_list: List[int], target_qubit_addr_list: List[int], alpha_angle: float) QCircuit

Create a RYY gate

Args:

qubit addr list : control qubit addr list qubit addr list : target qubit addr list double: gate rotation angle theta

Returns:

a RYY gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.RZ(qubit: Qubit, angle: float) QGate[源代码]
pyqpanda.pyQPanda.RZ(qubit_list: QVec, angle: float) QCircuit
pyqpanda.pyQPanda.RZ(qubit_addr: int, angle: float) QGate
pyqpanda.pyQPanda.RZ(qubit_addr_list: List[int], angle: float) QCircuit

Create a RZ gate Args:

qubit_list_addr: quantum gate qubits list addr args : quantum gate angles

Returns:

a RZ gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.RZX(control_qubit: Qubit, target_qubit: Qubit, alpha_angle: float) QGate[源代码]
pyqpanda.pyQPanda.RZX(control_qubit_list: QVec, target_qubit_list: QVec, alpha_angle: float) QCircuit
pyqpanda.pyQPanda.RZX(control_qubit_addr: int, target_qubit_addr: int, alpha_angle: float) QGate
pyqpanda.pyQPanda.RZX(control_qubit_addr_list: List[int], target_qubit_addr_list: List[int], alpha_angle: float) QCircuit

Create a RZX gate

Args:

qubit addr list : control qubit addr list qubit addr list : target qubit addr list double: gate rotation angle theta

Returns:

a RZX gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.RZZ(control_qubit: Qubit, target_qubit: Qubit, alpha_angle: float) QGate[源代码]
pyqpanda.pyQPanda.RZZ(control_qubit_list: QVec, target_qubit_list: QVec, alpha_angle: float) QCircuit
pyqpanda.pyQPanda.RZZ(control_qubit_addr: int, target_qubit_addr: int, alpha_angle: float) QGate
pyqpanda.pyQPanda.RZZ(control_qubit_addr_list: List[int], target_qubit_addr_list: List[int], alpha_angle: float) QCircuit

Create a RZZ gate

Args:

qubit addr list : control qubit addr list qubit addr list : target qubit addr list double: gate rotation angle theta

Returns:

a RZZ gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.Reset(qubit: Qubit) QReset[源代码]
pyqpanda.pyQPanda.Reset(qubit_addr: int) QReset

Create a Reset node

pyqpanda.pyQPanda.S(qubit: Qubit) QGate[源代码]
pyqpanda.pyQPanda.S(qubit_list: QVec) QCircuit
pyqpanda.pyQPanda.S(qubit_addr: int) QGate
pyqpanda.pyQPanda.S(qubit_addr_list: List[int]) QCircuit

Create a S gate

Args:

qubit_list_addr: quantum gate qubits list addr

Returns:

a S gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.SWAP(first_qubit: Qubit, second_qubit: Qubit) QGate[源代码]
pyqpanda.pyQPanda.SWAP(first_qubit_list: QVec, second_qubit_list: QVec) QCircuit
pyqpanda.pyQPanda.SWAP(first_qubit_addr: int, second_qubit_addr: int) QGate
pyqpanda.pyQPanda.SWAP(first_qubit_addr_list: List[int], second_qubit_addr_list: List[int]) QCircuit
Returns:

a SWAP gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.Shor_factorization(arg0: int) Tuple[bool, Tuple[int, int]][源代码]

Use Shor factorize integer num

Args:

int: target integer num result: Shor result

Returns:

result : Shor_factorization search result

Raises:

run_fail: An error occurred in Shor_factorization

pyqpanda.pyQPanda.SqiSWAP(first_qubit: Qubit, second_qubit: Qubit) QGate[源代码]
pyqpanda.pyQPanda.SqiSWAP(first_qubit_list: QVec, second_qubit_list: QVec) QCircuit
pyqpanda.pyQPanda.SqiSWAP(first_qubit_addr: int, second_qubit_addr: int) QGate
pyqpanda.pyQPanda.SqiSWAP(first_qubit_addr_list: List[int], second_qubit_addr_list: List[int]) QCircuit
Returns:

a SqiSWAP gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.T(qubit: Qubit) QGate[源代码]
pyqpanda.pyQPanda.T(qubit_list: QVec) QCircuit
pyqpanda.pyQPanda.T(qubit_addr: int) QGate
pyqpanda.pyQPanda.T(qubit_addr_list: List[int]) QCircuit

Create a T gate

Args:

qubit_list_addr: quantum gate qubits list addr

Returns:

a T gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.Toffoli(control_qubit_first: Qubit, control_qubit_second: Qubit, target_qubit: Qubit) QGate[源代码]
pyqpanda.pyQPanda.Toffoli(control_qubit_addr_first: int, control_qubit_addr_second: int, target_qubit_addr: int) QGate

Create a Toffoli gate

pyqpanda.pyQPanda.U1(qubit: Qubit, angle: float) QGate[源代码]
pyqpanda.pyQPanda.U1(qubit_list: QVec, angle: float) QCircuit
pyqpanda.pyQPanda.U1(qubit_addr: int, angle: float) QGate
pyqpanda.pyQPanda.U1(qubit_addr_list: List[int], angle: float) QCircuit

Create a U1 gate Args:

qubit_list_addr: quantum gate qubits list addr args : quantum gate angles

Returns:

a U1 gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.U2(qubit: Qubit, phi_angle: float, lambda_angle: float) QGate[源代码]
pyqpanda.pyQPanda.U2(qubit_list: QVec, phi_angle: float, lambda_angle: float) QCircuit
pyqpanda.pyQPanda.U2(qubit_addr: int, phi_angle: float, lambda_angle: float) QGate
pyqpanda.pyQPanda.U2(qubit_addr_list: List[int], phi_angle: float, lambda_angle: float) QCircuit

Create a U2 gate Args:

qubit_list_addr: quantum gate qubits list addr args : quantum gate angles

Returns:

a U2 gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.U3(qubit: Qubit, theta_angle: float, phi_angle: float, lambda_angle: float) QGate[源代码]
pyqpanda.pyQPanda.U3(qubit_list: QVec, theta_angle: float, phi_angle: float, lambda_angle: float) QCircuit
pyqpanda.pyQPanda.U3(qubit_addr: int, theta_angle: float, phi_angle: float, lambda_angle: float) QGate
pyqpanda.pyQPanda.U3(qubit_addr_list: List[int], theta_angle: float, phi_angle: float, lambda_angle: float) QCircuit

Create a U3 gate Args:

qubit_list_addr: quantum gate qubits list addr args : quantum gate angles

Returns:

a U3 gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.U4(matrix: List[complex], qubit: Qubit) QGate[源代码]
pyqpanda.pyQPanda.U4(alpha_angle: float, beta_angle: float, gamma_angle: float, delta_angle: float, qubit: Qubit) QGate
pyqpanda.pyQPanda.U4(qubit: Qubit, matrix: List[complex]) QGate
pyqpanda.pyQPanda.U4(qubit_list: QVec, matrix: List[complex]) QCircuit
pyqpanda.pyQPanda.U4(qubit_addr: int, matrix: List[complex]) QGate
pyqpanda.pyQPanda.U4(qubit_addr_list: List[int], matrix: List[complex]) QCircuit
pyqpanda.pyQPanda.U4(qubit: Qubit, alpha_anlge: float, beta_anlge: float, gamma_anlge: float, delta_anlge: float) QGate
pyqpanda.pyQPanda.U4(qubit_list: QVec, alpha_angle: float, beta_angle: float, gamma_angle: float, delta_angle: float) QCircuit
pyqpanda.pyQPanda.U4(qubit_addr: int, alpha_anlge: float, beta_anlge: float, gamma_anlge: float, delta_anlge: float) QGate
pyqpanda.pyQPanda.U4(qubit_addr_list: List[int], alpha_anlge: float, beta_anlge: float, gamma_anlge: float, delta_anlge: float) QCircuit

Create a U4 gate

Args:

double : u4 gate alpha angle double : u4 gate beta angle double : u4 gate gamma angle double : u4 gate delta angle qubit_addr_list : U4 gate target qubit_addr_list

Returns:

a U4 node

pyqpanda.pyQPanda.UMA(arg0: Qubit, arg1: Qubit, arg2: Qubit) QCircuit[源代码]

Quantum adder UMA module

pyqpanda.pyQPanda.VQG_CNOT_batch(*args, **kwargs) Any[源代码]

variational quantum CNOT batch gates

pyqpanda.pyQPanda.VQG_CU_batch(*args, **kwargs) Any[源代码]

variational quantum CU batch gates

pyqpanda.pyQPanda.VQG_CZ_batch(*args, **kwargs) Any[源代码]

variational quantum CZ batch gates

pyqpanda.pyQPanda.VQG_H_batch(*args, **kwargs) Any[源代码]

variational quantum H batch gates

pyqpanda.pyQPanda.VQG_I_batch(*args, **kwargs) Any[源代码]

variational quantum I batch gates

pyqpanda.pyQPanda.VQG_SWAP_batch(*args, **kwargs) Any[源代码]

variational quantum SWAP batch gates

pyqpanda.pyQPanda.VQG_S_batch(*args, **kwargs) Any[源代码]

variational quantum S batch gates

pyqpanda.pyQPanda.VQG_SqiSWAP_batch(*args, **kwargs) Any[源代码]

variational quantum SqiSWAP batch gates

pyqpanda.pyQPanda.VQG_T_batch(*args, **kwargs) Any[源代码]

variational quantum T batch gates

pyqpanda.pyQPanda.VQG_U1_batch(*args, **kwargs) Any[源代码]

variational quantum U1 batch gates

pyqpanda.pyQPanda.VQG_U2_batch(*args, **kwargs) Any[源代码]

variational quantum U2 batch gates

pyqpanda.pyQPanda.VQG_U3_batch(*args, **kwargs) Any[源代码]

variational quantum U3 batch gates

pyqpanda.pyQPanda.VQG_U4_batch(*args, **kwargs) Any[源代码]

variational quantum U4 batch gates

pyqpanda.pyQPanda.VQG_X1_batch(*args, **kwargs) Any[源代码]

variational quantum X1 batch gates

pyqpanda.pyQPanda.VQG_X_batch(*args, **kwargs) Any[源代码]

variational quantum X batch gates

pyqpanda.pyQPanda.VQG_Y1_batch(*args, **kwargs) Any[源代码]

variational quantum Y1 batch gates

pyqpanda.pyQPanda.VQG_Y_batch(*args, **kwargs) Any[源代码]

variational quantum Y batch gates

pyqpanda.pyQPanda.VQG_Z1_batch(*args, **kwargs) Any[源代码]

variational quantum Z1 batch gates

pyqpanda.pyQPanda.VQG_Z_batch(*args, **kwargs) Any[源代码]

variational quantum Z batch gates

pyqpanda.pyQPanda.VQG_iSWAP_batch(*args, **kwargs) Any[源代码]

variational quantum iSWAP batch gates

pyqpanda.pyQPanda.X(qubit: Qubit) QGate[源代码]
pyqpanda.pyQPanda.X(qubit_list: QVec) QCircuit
pyqpanda.pyQPanda.X(qubit_addr: int) QGate
pyqpanda.pyQPanda.X(qubit_addr_list: List[int]) QCircuit

Create a X gate

Args:

qubit_list_addr: quantum gate qubits list addr

Returns:

a X gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.X1(qubit: Qubit) QGate[源代码]
pyqpanda.pyQPanda.X1(qubit_list: QVec) QCircuit
pyqpanda.pyQPanda.X1(qubit_addr: int) QGate
pyqpanda.pyQPanda.X1(qubit_addr_list: List[int]) QCircuit

Create a X1 gate

Args:

qubit_list_addr: quantum gate qubits list addr

Returns:

a X1 gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.Y(qubit: Qubit) QGate[源代码]
pyqpanda.pyQPanda.Y(qubit_list: QVec) QCircuit
pyqpanda.pyQPanda.Y(qubit_addr: int) QGate
pyqpanda.pyQPanda.Y(qubit_addr_list: List[int]) QCircuit

Create a Y gate

Args:

qubit_list_addr: quantum gate qubits list addr

Returns:

a Y gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.Y1(qubit: Qubit) QGate[源代码]
pyqpanda.pyQPanda.Y1(qubit_list: QVec) QCircuit
pyqpanda.pyQPanda.Y1(qubit_addr: int) QGate
pyqpanda.pyQPanda.Y1(qubit_addr_list: List[int]) QCircuit

Create a Y1 gate

Args:

qubit_list_addr: quantum gate qubits list addr

Returns:

a Y1 gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.Z(qubit: Qubit) QGate[源代码]
pyqpanda.pyQPanda.Z(qubit_list: QVec) QCircuit
pyqpanda.pyQPanda.Z(qubit_addr: int) QGate
pyqpanda.pyQPanda.Z(qubit_addr_list: List[int]) QCircuit

Create a Z gate

Args:

qubit_list_addr: quantum gate qubits list addr

Returns:

a Z gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.Z1(qubit: Qubit) QGate[源代码]
pyqpanda.pyQPanda.Z1(qubit_list: QVec) QCircuit
pyqpanda.pyQPanda.Z1(qubit_addr: int) QGate
pyqpanda.pyQPanda.Z1(qubit_addr_list: List[int]) QCircuit

Create a Z1 gate

Args:

qubit_list_addr: quantum gate qubits list addr

Returns:

a Z1 gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.accumulateProbability(probability_list: List[float]) List[float][源代码]

Accumulate the probability from a prob list

Args:

probability_list: measured result in probability list form

Returns:

accumulated resultRaises: run_fail: An error occurred in accumulateProbability

pyqpanda.pyQPanda.accumulate_probabilities(probability_list: List[float]) List[float][源代码]

Accumulate the probability from a prob list

Args:

probability_list: measured result in probability list form

Returns:

accumulated resultRaises: run_fail: An error occurred in accumulate_probabilities

pyqpanda.pyQPanda.accumulate_probability(probability_list: List[float]) List[float][源代码]

Accumulate the probability from a prob list

Args:

probability_list: measured result in probability list form

Returns:

accumulated resultRaises: run_fail: An error occurred in accumulate_probability

pyqpanda.pyQPanda.acos(arg0: var) var[源代码]
pyqpanda.pyQPanda.add(arg0: ClassicalCondition, arg1: ClassicalCondition) ClassicalCondition[源代码]
pyqpanda.pyQPanda.add(arg0: ClassicalCondition, arg1: int) ClassicalCondition
pyqpanda.pyQPanda.add(arg0: int, arg1: ClassicalCondition) ClassicalCondition
pyqpanda.pyQPanda.all_cut_of_graph(adjacent_matrix: List[List[float]], all_cut_list: List[float], target_value_list: List[int]) float[源代码]

Generate graph of maxcut problem

Args:

adjacent_matrix: adjacent_matrix for quantum prog all_cut_list: all cut graph list in quantum prog target_value_list: target cut value list

Returns:

max value

Raises:

run_fail: An error occurred in all_cut_of_graph

pyqpanda.pyQPanda.amplitude_encode(qubit: QVec, data: List[float], b_need_check_normalization: bool = True) QCircuit[源代码]
pyqpanda.pyQPanda.amplitude_encode(qubit: QVec, data: List[complex]) QCircuit

Encode the input double data to the amplitude of qubits

Args:

qubit: quantum program qubits data: double data list

Returns:

result circuit

Raises:

run_fail: An error occurred in amplitude_encode

pyqpanda.pyQPanda.apply_QGate(qubit_list: QVec, func_obj: Callable[[Qubit], QGate]) QCircuit[源代码]
pyqpanda.pyQPanda.apply_QGate(qubit_addr_list: List[int], func_obj: Callable[[int], QGate]) QCircuit

Apply QGate to qubits

Args:

qubit_addr_list: qubit address list func_obj: QGate(int) like function object accept Qubit address as argument

Returns:

QCircuit contain QGate operation on all qubit

pyqpanda.pyQPanda.asin(arg0: var) var[源代码]
pyqpanda.pyQPanda.assign(arg0: ClassicalCondition, arg1: ClassicalCondition) ClassicalCondition[源代码]
pyqpanda.pyQPanda.assign(arg0: ClassicalCondition, arg1: int) ClassicalCondition
pyqpanda.pyQPanda.atan(arg0: var) var[源代码]
pyqpanda.pyQPanda.average_gate_fidelity(state1: numpy.ndarray[numpy.complex128[m, n]], state2: List[complex]) float[源代码]
pyqpanda.pyQPanda.average_gate_fidelity(state1: numpy.ndarray[numpy.complex128[m, n]], state2: numpy.ndarray[numpy.complex128[m, n]]) float

compare two quantum states , Get the state fidelity

Args:

state1: quantum state matrix 1 state2: quantum state list 2

Returns:

state fidelity bewteen [0,1]

pyqpanda.pyQPanda.bin_to_prog(bin_data: List[int], qubit_list: QVec, cbit_list: List[ClassicalCondition], qprog: QProg) bool[源代码]

Parse binary data transfor to quantum program Args:

bin_data: binary data stores quantum prog information qubit_list: quantum qubits list cbit_list: quantum cbits list qprog: quantum prog

Returns:

prog

pyqpanda.pyQPanda.bind_data(arg0: int, arg1: QVec) QCircuit[源代码]
Args:

int: classical data QVec: qubits list

Returns:

result : circuit

Raises:

run_fail: An error occurred in bind_data

pyqpanda.pyQPanda.bind_nonnegative_data(arg0: int, arg1: QVec) QCircuit[源代码]
Args:

int: classical data QVec: qubits list

Returns:

result : circuit

Raises:

run_fail: An error occurred in bind_nonnegative_data

pyqpanda.pyQPanda.build_HHL_circuit(matrix_A: List[complex], data_b: List[float], qvm: QuantumMachine, precision_cnt: int = 0) QCircuit[源代码]

build the quantum circuit for HHL algorithm to solve the target linear systems of equations : Ax = b

Args:

matrix_A: a unitary matrix or Hermitian N*N matrix with N = 2 ^ n data_b: a given vector qvm: quantum machine precision_cnt: The count of digits after the decimal point,

default is 0, indicates that there are only integer solutions

Returns:

QCircuit The whole quantum circuit for HHL algorithm

Notes:

The higher the precision is, the more qubit number and circuit - depth will be, for example: 1 - bit precision, 4 additional qubits are required, for 2 - bit precision, we need 7 additional qubits, and so on. The final solution = (HHL result) * (normalization factor for b) * (1 << ceil(log2(pow(10, precision_cnt))))

pyqpanda.pyQPanda.cAlloc() ClassicalCondition[源代码]
pyqpanda.pyQPanda.cAlloc(cbit_addr: int) ClassicalCondition

Allocate a CBit After init()

Args:

cbit_addr: cbit address, should in [0,29)

Returns:

classic result cbit

pyqpanda.pyQPanda.cAlloc_many(cbit_num: int) List[ClassicalCondition][源代码]

Allocate several CBits After init()

Args:

cbit_num: numbers of cbit want to be created

Returns:

list of cbit

pyqpanda.pyQPanda.cFree(cbit: ClassicalCondition) None[源代码]

Free a CBit

Args:

CBit: a CBit

Returns:

none

pyqpanda.pyQPanda.cFree_all() None[源代码]
pyqpanda.pyQPanda.cFree_all(cbit_list: List[ClassicalCondition]) None

Free all cbits

Args:

a list of cbits

Returns:

none

pyqpanda.pyQPanda.calculate_quantum_volume(noise_qvm: NoiseQVM, qubit_list: List[List[int]], ntrials: int, shots: int = 1000) int[源代码]
pyqpanda.pyQPanda.calculate_quantum_volume(cloud_qvm, qubit_list: List[List[int]], ntrials: int, shots: int = 1000) int
pyqpanda.pyQPanda.calculate_quantum_volume(config: QCloudTaskConfig, qubit_list: List[List[int]], ntrials: int) int

calculate quantum volume

Args:

config: QCloudTaskConfig qubit_list: qubit list ntrials: ntrials

Returns:

result data dict

Raises:

run_fail: An error occurred in calculate_quantum_volume

pyqpanda.pyQPanda.cast_qprog_qcircuit(qprog: QProg) QCircuit[源代码]

Cast QProg to QCircuit

Args:

qprog: quantum prog

Returns:

none

Raises:

run_fail: An error occurred in cast_qprog_qcircuit

pyqpanda.pyQPanda.cast_qprog_qgate(qprog: QProg) QGate[源代码]

Cast QProg to QGate

Args:

qprog: quantum prog

Returns:

none

Raises:

run_fail: An error occurred in cast_qprog_qgate

pyqpanda.pyQPanda.cast_qprog_qmeasure(qprog: QProg) QMeasure[源代码]

Cast QProg to QMeasure

Args:

qprog: quantum prog

Returns:

none

Raises:

run_fail: An error occurred in cast_qprog_qmeasure

pyqpanda.pyQPanda.circuit_layer(qprog: QProg) list[源代码]

Quantum circuit layering

Args:

QProg: quantum prog

Returns:

result data tuple contains layer info

Raises:

run_fail: An error occurred in get circuit_layer

pyqpanda.pyQPanda.circuit_optimizer(qprog: QProg, optimizer_cir_vec: List[Tuple[QCircuit, QCircuit]] = [], mode_list: List[QCircuitOPtimizerMode] = []) QProg[源代码]

Optimize QCircuit

Args:

qprog: quantum program optimizer_cir_vec: quantum circuit list mode_list: optimize mode list

Returns:

a new prog after optimize

pyqpanda.pyQPanda.circuit_optimizer_by_config(qprog: QProg, config_file: str = 'QPandaConfig.json', mode_list: List[QCircuitOPtimizerMode] = []) QProg[源代码]

QCircuit optimizer

Args:

qprog: quantum program config_file: optimize config mode_list: optimize mode list

Returns:

a new prog after optimize

pyqpanda.pyQPanda.comm_protocol_decode(encode_data: bytes, machine: QuantumMachine) Tuple[List[QProg], CommProtocolConfig][源代码]

decode binary data to comm protocol prog list

Args:

encode_data: quantum prog_list encode data

Returns:

result prog list

Raises:

run_fail: An error occurred in comm_protocol_decode

pyqpanda.pyQPanda.comm_protocol_encode(prog: QProg, config: CommProtocolConfig = ...) bytes[源代码]
pyqpanda.pyQPanda.comm_protocol_encode(prog_list: List[QProg], config: CommProtocolConfig = ...) bytes

encode comm protocol data to binary data

Args:

prog_list: quantum prog_list config: comm_protocol config

Returns:

result data list

Raises:

run_fail: An error occurred in comm_protocol_encode

pyqpanda.pyQPanda.constModAdd(arg0: QVec, arg1: int, arg2: int, arg3: QVec, arg4: QVec) QCircuit[源代码]
Args:

QVec qvec int base int module_Num QVec qvec1 QVec qvec2

Returns:

result circuit

Raises:

run_fail: An error occurred in constModAdd

pyqpanda.pyQPanda.constModExp(arg0: QVec, arg1: QVec, arg2: int, arg3: int, arg4: QVec, arg5: QVec, arg6: QVec) QCircuit[源代码]
Args:

QVec qvec int base int module_Num QVec qvec1 QVec qvec2

Returns:

result circuit

Raises:

run_fail: An error occurred in constModExp

pyqpanda.pyQPanda.constModMul(arg0: QVec, arg1: int, arg2: int, arg3: QVec, arg4: QVec, arg5: QVec) QCircuit[源代码]
Args:

QVec qvec int base int module_Num QVec qvec1 QVec qvec2

Returns:

result circuit

Raises:

run_fail: An error occurred in constModMul

pyqpanda.pyQPanda.convert_binary_data_to_qprog(machine: QuantumMachine, data: List[int]) QProg[源代码]

Parse binary data to quantum program

Args:

machine: quantum machine data: quantum prog data

Returns:

quantum prog

Raises:

run_fail: An error occurred in convert_binary_data_to_qprog

pyqpanda.pyQPanda.convert_originir_str_to_qprog(originir_str: str, machine: QuantumMachine) list[源代码]

Trans OriginIR to QProg

Args:

originir_str: OriginIR string machine: initialized quantum machine

Returns:

list cotains QProg, qubit_list, cbit_listRaises: run_fail: An error occurred in convert_originir_str_to_qprog

pyqpanda.pyQPanda.convert_originir_to_qprog(file_path: str, machine: QuantumMachine) list[源代码]

Read OriginIR file and trans to QProg

Args:

file_path: OriginIR file path machine: initialized quantum machine

Returns:

list cotains QProg, qubit_list, cbit_listRaises: run_fail: An error occurred in convert_originir_to_qprog

pyqpanda.pyQPanda.convert_qasm_string_to_qprog(qasm_str: str, machine: QuantumMachine) list[源代码]

Trans QASM to QProg

Args:

qasm_str: QASM string machine: initialized quantum machine

Returns:

list cotains QProg, qubit_list, cbit_list

pyqpanda.pyQPanda.convert_qasm_to_qprog(file_path: str, machine: QuantumMachine) list[源代码]

Read QASM file and trans to QProg

Args:

file_path: QASM file path machine: initialized quantum machine

Returns:

list cotains QProg, qubit_list, cbit_listRaises: run_fail: An error occurred in convert_qasm_to_qprog

pyqpanda.pyQPanda.convert_qprog_to_binary(qprog: QProg, machine: QuantumMachine) List[int][源代码]
pyqpanda.pyQPanda.convert_qprog_to_binary(qprog: QProg, machine: QuantumMachine, fname: str) None

Store quantum program in binary file Args:

machine: quantum machine qprog: quantum prog fname: binary data file name

Returns:

none

pyqpanda.pyQPanda.convert_qprog_to_originir(qprog: QProg, machine: QuantumMachine) str[源代码]
Args:

qprog: quantum prog machine: quantum machine

Returns:

originir : originir string , see originir indroduction :https://pyqpanda-toturial.readthedocs.io/zh/latest/QProgToOriginIR.html

pyqpanda.pyQPanda.convert_qprog_to_qasm(qprog: QProg, machine: QuantumMachine) str[源代码]

Convert QProg to QASM instruction string

Args:

machine: quantum machine qprog: quantum prog

Returns:

qsm string stores prog

Raises:

run_fail: An error occurred in convert_qprog_to_qasm

pyqpanda.pyQPanda.convert_qprog_to_quil(qprog: QProg, machine: QuantumMachine) str[源代码]

convert QProg to Quil instruction

Args:

qprog: QProg machine: quantum machine

Returns:

Quil instruction string

pyqpanda.pyQPanda.cos(arg0: var) var[源代码]
pyqpanda.pyQPanda.count_gate(quantum_prog: QProg) int[源代码]
pyqpanda.pyQPanda.count_gate(quantum_circuit: QCircuit) int

Count quantum gate num under quantum program, quantum circuit Args:

circuit : quantum_circuit

Returns:

result: gate count

Raises:

run_fail: An error occurred in get_qgate_num

pyqpanda.pyQPanda.count_prog_info(node: QProg, selected_types: List[GateType] = []) ProgCount[源代码]
pyqpanda.pyQPanda.count_prog_info(node: QCircuit, selected_types: List[GateType] = []) ProgCount

count quantum program info Args:

qprog: QProg optimize: whether to enable the optimization circuit switch.

Returns:

ProgCount struct

pyqpanda.pyQPanda.count_qgate_num(prog: QProg, gate_type: int = -1) int[源代码]
pyqpanda.pyQPanda.count_qgate_num(circuit: QCircuit, gate_type: int = -1) int

Count quantum gate num under quantum program

Args:

quantum_circuit: QCircuit& gtype: const GateType

Returns:

this GateType quantum gate num

pyqpanda.pyQPanda.create_empty_circuit() QCircuit[源代码]

Create an empty QCircuit Container

Args:

none

Returns:

a empty QCircuit

pyqpanda.pyQPanda.create_empty_qprog() QProg[源代码]

Create an empty QProg Container

Args:

none

Returns:

a empty QProg

pyqpanda.pyQPanda.create_if_prog(classical_condition: ClassicalCondition, true_node: QProg) QIfProg[源代码]
pyqpanda.pyQPanda.create_if_prog(classical_condition: ClassicalCondition, true_node: QProg, false_node: QProg) QIfProg

Create a classical quantum IfProg

Args:

classical_condition: quatum cbit true_node: quantum IfProg true qnode false_node: quantum IfProg false qnode

Returns:

a classical quantum IfProg

pyqpanda.pyQPanda.create_while_prog(classical_condition: ClassicalCondition, true_node: QProg) QWhileProg[源代码]

Create a WhileProg

Args:

classical_condition: quatum cbit true_node: quantum QWhile qnode

Returns:

a WhileProg

pyqpanda.pyQPanda.crossEntropy(arg0: var, arg1: var) var[源代码]
pyqpanda.pyQPanda.decompose_multiple_control_qgate(qprog: QProg, machine: QuantumMachine, config_file: str = 'QPandaConfig.json') QProg[源代码]
pyqpanda.pyQPanda.decompose_multiple_control_qgate(qprog: QProg, machine: QuantumMachine, convert_single_gates: List[str], convert_double_gates: List[str], b_transform_to_base_qgate: bool = True) QProg

Decompose multiple control QGate

Args:

qprog: quantum program machine: quantum machine convert_single_gates: quantum single gates sets convert_double_gates: quantum double gates sets transform_to_base_qgate: transform to base qgate sets

Returns:

a new prog after decomposition

pyqpanda.pyQPanda.deep_copy(node: QProg) QProg[源代码]
pyqpanda.pyQPanda.deep_copy(node: QCircuit) QCircuit
pyqpanda.pyQPanda.deep_copy(node: QGate) QGate
pyqpanda.pyQPanda.deep_copy(node: QMeasure) QMeasure
pyqpanda.pyQPanda.deep_copy(node: ClassicalProg) ClassicalProg
pyqpanda.pyQPanda.deep_copy(node: QIfProg) QIfProg
pyqpanda.pyQPanda.deep_copy(node: QWhileProg) QWhileProg
pyqpanda.pyQPanda.del_weak_edge(topo_data: List[List[int]]) None[源代码]

Delete weakly connected edges

Args:

topo_data: quantum program topo_data

Returns:

none

Raises:

run_fail: An error occurred in del_weak_edge

pyqpanda.pyQPanda.del_weak_edge2(topo_data: List[List[int]], max_connect_degree: int, sub_graph_set: List[int]) list[源代码]

Delete weakly connected edges

Args:

topo_data: quantum program topo_data max_connect_degree: max value of connect degree sub_graph_set: sub graph set list

Returns:

result data

Raises:

run_fail: An error occurred in del_weak_edge2

pyqpanda.pyQPanda.del_weak_edge3(topo_data: List[List[int]], sub_graph_set: List[int], max_connect_degree: int, lamda1: float, lamda2: float, lamda3: float) list[源代码]

Delete weakly connected edges

Args:

topo_data: quantum program topo_data max_connect_degree: max value of connect degree sub_graph_set: sub graph set list lamda1: lamda1 lamda2: lamda2 lamda3: lamda3

Returns:

result data

Raises:

run_fail: An error occurred in del_weak_edge3

pyqpanda.pyQPanda.destroy_quantum_machine(machine: QuantumMachine) None[源代码]

Destroy a quantum machine

Args:

machine: type should be one of CPUQVM, CPUSingleThreadQVM, GPUQVM, NoiseQVM

Returns:

noneRaises: run_fail: An error occurred in destroy_quantum_machine

pyqpanda.pyQPanda.directly_run(qprog: QProg, noise_model: Noise = NoiseModel()) Dict[str, bool][源代码]

Directly run quantum prog After init()

Args:

qprog: quantum program noise_model: noise model, default is no noise. noise model only work on CPUQVM now

Returns:
Dict[str, bool]: result of quantum program execution one shot.

first is the final qubit register state, second is it's measure probability

pyqpanda.pyQPanda.div(arg0: ClassicalCondition, arg1: ClassicalCondition) ClassicalCondition[源代码]
pyqpanda.pyQPanda.div(arg0: ClassicalCondition, arg1: int) ClassicalCondition
pyqpanda.pyQPanda.div(arg0: int, arg1: ClassicalCondition) ClassicalCondition
pyqpanda.pyQPanda.dot(arg0: var, arg1: var) var[源代码]
pyqpanda.pyQPanda.double_gate_xeb(config: QCloudTaskConfig, qubit0: int, qubit1: int, clifford_range: List[int], num_circuits: int, gate_type: GateType = GateType.CZ_GATE) Dict[int, float][源代码]
pyqpanda.pyQPanda.double_gate_xeb(qvm: QuantumMachine, qubit0: Qubit, qubit1: Qubit, clifford_range: List[int], num_circuits: int, shots: int, chip_id: int = 2, gate_type: GateType = GateType.CZ_GATE) Dict[int, float]

double gate xeb

Args:

qvm: quantum machine qubit0: double qubit 0 qubit1: double qubit 1 clifford_range: clifford range list num_circuits: the num of circuits shots: measure shots chip type: RealChipType interleaved_gates: interleaved gates list

Returns:

result data dict

Raises:

run_fail: An error occurred in double_gate_xeb

pyqpanda.pyQPanda.double_qubit_rb(qvm: QuantumMachine, qubit0: Qubit, qubit1: Qubit, clifford_range: List[int], num_circuits: int, shots: int, chip_id: int = 2, interleaved_gates: List[QGate] = []) Dict[int, float][源代码]
pyqpanda.pyQPanda.double_qubit_rb(config: QCloudTaskConfig, qubit0: int, qubit1: int, clifford_range: List[int], num_circuits: int, interleaved_gates: List[QGate] = []) Dict[int, float]

double qubit rb with origin chip Args:

config: QCloudTaskConfig qubit0: double qubit 0 qubit1: double qubit 1 clifford_range: clifford range list num_circuits: the num of circuits interleaved_gates: interleaved gates list

Returns:

result data dict

Raises:

run_fail: An error occurred in double_qubit_rb

pyqpanda.pyQPanda.draw_qprog_latex(prog: QProg, auto_wrap_len: int = 100, output_file: str = 'QCircuit.tex', with_logo: bool = False, itr_start: NodeIter = NodeIter(), itr_end: NodeIter = NodeIter()) str[源代码]

Convert a quantum prog/circuit to latex source code, and save the source code to file in current path with name QCircuit.tex Args:

QProg: quantum prog auto_wrap_len: defaut is 100 output_file: result output file name itr_start: nodeiter start itr_end: nodeiter end

Returns:

result data tuple contains prog info

Raises:

run_fail: An error occurred in get draw_qprog_text

pyqpanda.pyQPanda.draw_qprog_latex_with_clock(prog: QProg, config_data: str = 'QPandaConfig.json', auto_wrap_len: bool = 100, output_file: int = 'QCircuit.tex', with_logo: str = False, itr_start: NodeIter = NodeIter(), itr_end: NodeIter = NodeIter()) str[源代码]

Convert a quantum prog/circuit to latex source code with time sequence, and save the source code to file in current path with name QCircuit.tex Args:

QProg: quantum prog config_data: default config file is QPandaConfig.json auto_wrap_len: defaut is 100 output_file: result output file name itr_start: nodeiter start itr_end: nodeiter end

Returns:

result data tuple contains prog info

Raises:

run_fail: An error occurred in get draw_qprog_text

pyqpanda.pyQPanda.draw_qprog_text(qprog: QProg, auto_wrap_len: int = 100, output_file: str = 'QCircuitTextPic.txt', itr_start: NodeIter = NodeIter(), itr_end: NodeIter = NodeIter()) str[源代码]

Convert a quantum prog/circuit to text-pic(UTF-8 code), and will save the text-pic in file named QCircuitTextPic.txt in the same time in current path Args:

QProg: quantum prog auto_wrap_len: defaut is 100 output_file: result output file name itr_start: nodeiter start itr_end: nodeiter end

Returns:

result data tuple contains prog info

Raises:

run_fail: An error occurred in get draw_qprog_text

pyqpanda.pyQPanda.draw_qprog_text_with_clock(prog: QProg, config_data: str = 'QPandaConfig.json', auto_wrap_len: int = 100, output_file: str = 'QCircuitTextPic.txt', itr_start: NodeIter = NodeIter(), itr_end: NodeIter = NodeIter()) str[源代码]

Convert a quantum prog/circuit to text-pic(UTF-8 code) with time sequence, and will save the text-pic in file named QCircuitTextPic.txt in the same time in current path Args:

QProg: quantum prog auto_wrap_len: defaut is 100 output_file: result output file name itr_start: nodeiter start itr_end: nodeiter end

Returns:

result data tuple contains prog info

Raises:

run_fail: An error occurred in get draw_qprog_text

pyqpanda.pyQPanda.dropout(arg0: var, arg1: var) var[源代码]
pyqpanda.pyQPanda.equal(arg0: ClassicalCondition, arg1: ClassicalCondition) ClassicalCondition[源代码]
pyqpanda.pyQPanda.equal(arg0: ClassicalCondition, arg1: int) ClassicalCondition
pyqpanda.pyQPanda.equal(arg0: int, arg1: ClassicalCondition) ClassicalCondition
pyqpanda.pyQPanda.estimate_topology(topo_data: List[List[int]]) float[源代码]

Evaluate topology performance

Args:

topo_data: quantum program topo data

Returns:

result data

Raises:

run_fail: An error occurred in estimate_topology

pyqpanda.pyQPanda.eval(arg0: var, arg1: bool) numpy.ndarray[numpy.float64[m, n]][源代码]
pyqpanda.pyQPanda.eval(arg0: var) numpy.ndarray[numpy.float64[m, n]]
pyqpanda.pyQPanda.exp(arg0: var) var[源代码]
pyqpanda.pyQPanda.expMat(arg0: complex, arg1: numpy.ndarray[numpy.complex128[m, n]], arg2: float) numpy.ndarray[numpy.complex128[m, n]][源代码]

calculate the matrix power of e

pyqpanda.pyQPanda.expand_linear_equations(matrix: List[complex], list: List[float]) expand_linear_equations.list[源代码]
pyqpanda.pyQPanda.expand_linear_equations(matrix: List[complex], list: List[float]) expand_linear_equations.list

Extending linear equations to N dimension, N = 2 ^ n

Args:

matrix: the source matrix, which will be extend to N*N, N = 2 ^ n list: the source vector b, which will be extend to 2 ^ n

pyqpanda.pyQPanda.fill_qprog_by_I(qprog: QProg) QProg[源代码]

Fill the input QProg by I gate, return a new quantum program

Args:

prog: quantum prog

Returns:

a new quantum program

Raises:

run_fail: An error occurred in get fill_qprog_by_I

pyqpanda.pyQPanda.finalize() None[源代码]

Finalize the environment and destory global unique quantum machine.

Args:

none

Returns:

none

pyqpanda.pyQPanda.fit_to_gbk(utf8_str: str) str[源代码]

Special character conversion

Args:

utf8_str: string using utf-8 encode

Returns:

result string

Raises:

run_fail: An error occurred in get fit_to_gbk

pyqpanda.pyQPanda.flatten(qprog: QProg) None[源代码]
pyqpanda.pyQPanda.flatten(qcircuit: QCircuit) None

Flatten quantum circuit

Args:

qprog: quantum circuit

Returns:

none

pyqpanda.pyQPanda.getAllocateCMem() int[源代码]

Deprecated, use get_allocate_cmem_num instead Args:

none

Returns:

allocate qubit num

Raises:

run_fail: An error occurred in get_allocate_cmem_num

pyqpanda.pyQPanda.getAllocateQubitNum() int[源代码]

Deprecated, use get_allocate_qubit_num instead Args:

none

Returns:

allocate cbit num

Raises:

run_fail: An error occurred in get_allocate_qubit_num

pyqpanda.pyQPanda.get_adjacent_qgate_type(qprog: QProg, node_iter: NodeIter) List[NodeInfo][源代码]

Get the adjacent quantum gates's(the front one and the back one) typeinfo from QProg

Args:

qprog: target quantum program node_iter: gate node iter in qprog

Returns:

the front one and back node info of node_iter in qprog

pyqpanda.pyQPanda.get_all_used_qubits(qprog: QProg) QVec[源代码]

Get all the used quantum bits in the input prog Args:

qprog: quantum program

Returns:

all used qubits

pyqpanda.pyQPanda.get_all_used_qubits_to_int(qprog: QProg) List[int][源代码]

Get all the used quantum bits addr in the input prog Args:

qprog: quantum program

Returns:

all used qubits

pyqpanda.pyQPanda.get_allocate_cbits() List[ClassicalCondition][源代码]

Get allocated cbits of QuantumMachine

Args:

none

Returns:

cbit list

Raises:

run_fail: An error occurred in allocated cbits of QuantumMachine

pyqpanda.pyQPanda.get_allocate_cmem_num() int[源代码]

get allocate cmem num Args:

none

Returns:

qubit_num : allocate cbit num

Raises:

run_fail: An error occurred in get_allocate_cmem_num

pyqpanda.pyQPanda.get_allocate_qubit_num() int[源代码]

get allocate qubit num

Args:

none

Returns:

qubit_num : allocate qubit num

Raises:

run_fail: An error occurred in get_allocate_qubit_num

pyqpanda.pyQPanda.get_allocate_qubits() QVec[源代码]

Get allocated qubits of QuantumMachine

Args:

none

Returns:

qubit list

Raises:

run_fail: An error occurred in allocated qubits of QuantumMachine

pyqpanda.pyQPanda.get_bin_data(qprog: QProg) List[int][源代码]

Get quantum program binary data

Args:

qprog: QProg machine: quantum machine

Returns:

binary data in list

pyqpanda.pyQPanda.get_bin_str(qprog: QProg, machine: QuantumMachine) str[源代码]

Transfor quantum program to string Args:

machine: quantum machine qprog: quantum prog

Returns:

string for bin_str

pyqpanda.pyQPanda.get_circuit_optimal_topology(qprog: QProg, machine: QuantumMachine, max_connect_degree: int, config_file: str = 'QPandaConfig.json') List[List[int]][源代码]

Get the optimal topology of the input circuit

Args:

qprog: quantum program machine: quantum machine max_connect_degree: max value of connect degree config_file: config file

Returns:

Topology prog DataRaises: run_fail: An error occurred in get_circuit_optimal_topology

pyqpanda.pyQPanda.get_clock_cycle(qpog: QProg) int[源代码]

Get quantum program clock cycle Args:

qprog: QProg

Returns:

clock_cycle

pyqpanda.pyQPanda.get_complex_points(topo_data: List[List[int]], max_connect_degree: int) List[int][源代码]

Get complex points

Args:

topo_data: quantum program topo_data max_connect_degree: max value of connect degree

Returns:

complex points list

Raises:

run_fail: An error occurred in get_complex_points

pyqpanda.pyQPanda.get_double_gate_block_topology(qprog: QProg) List[List[int]][源代码]

get double gate block topology

Args:

qprog: quantum program

Returns:

Topology prog DataRaises: run_fail: An error occurred in get_double_gate_block_topology

pyqpanda.pyQPanda.get_matrix(qprog: QProg, positive_seq: bool = False, nodeitr_start: NodeIter = NodeIter(), nodeitr_end: NodeIter = NodeIter()) List[complex][源代码]

Get the target matrix between the input two Nodeiters

Args:

qprog: quantum program positive_seq: Qubit order of output matrix

true for positive sequence(q0q1q2), false for inverted order(q2q1q0), default is false

nodeiter_start: the start NodeIter nodeiter_end: the end NodeIter

Returns:

target matrix include all the QGate's matrix (multiply)

pyqpanda.pyQPanda.get_prob_dict(qubit_list: QVec, select_max: int = -1) Dict[str, float][源代码]

Get pmeasure result as dict

Args:

qubit_list: pmeasure qubits list select_max: max returned element num in returnd tuple, should in [-1, 1<<len(qubit_list)]

default is -1, means no limit

Returns:

measure result of quantum machine

Raises:

run_fail: An error occurred in get_prob_dict

pyqpanda.pyQPanda.get_prob_list(qubit_list: QVec, select_max: int = -1) List[float][源代码]

Get pmeasure result as list

Args:

qubit_list: pmeasure qubits list select_max: max returned element num in returnd tuple, should in [-1, 1<<len(qubit_list)]

default is -1, means no limit

Returns:

measure result of quantum machine

Raises:

run_fail: An error occurred in get_prob_list

pyqpanda.pyQPanda.get_qgate_num(quantum_prog: QProg) int[源代码]
pyqpanda.pyQPanda.get_qgate_num(quantum_circuit: QCircuit) int
pyqpanda.pyQPanda.get_qgate_num(qprog: QProg) int

Count quantum gate num under quantum program

Args:

qprog: quantum prog

Returns:

quantum gate num under quantum program

pyqpanda.pyQPanda.get_qprog_clock_cycle(qprog: QProg, machine: QuantumMachine, optimize: bool = False) int[源代码]

Get Quantum Program Clock Cycle

Args:

qprog: quantum program machine: quantum machine optimize: optimize qprog

Returns:

QProg time comsume, no unit, not in seconds

pyqpanda.pyQPanda.get_qstate() List[complex][源代码]
pyqpanda.pyQPanda.get_qstate() Any
pyqpanda.pyQPanda.get_sub_graph(topo_data: List[List[int]]) List[int][源代码]

Get sub graph

Args:

topo_data: quantum program topo data

Returns:

sub graph

Raises:

run_fail: An error occurred in sub graph

pyqpanda.pyQPanda.get_tuple_list(qubit_list: QVec, select_max: int = -1) List[Tuple[int, float]][源代码]

Get pmeasure result as tuple list

Args:

qubit_list: pmeasure qubits list select_max: max returned element num in returnd tuple, should in [-1, 1<<len(qubit_list)]

default is -1, means no limit

Returns:

measure result of quantum machine

Raises:

run_fail: An error occurred in get_tuple_list

pyqpanda.pyQPanda.get_unitary(qprog: QProg, positive_seq: bool = False, nodeitr_start: NodeIter = NodeIter(), nodeitr_end: NodeIter = NodeIter()) List[complex][源代码]

Get the target matrix between the input two Nodeiters

Args:

qprog: quantum program positive_seq: Qubit order of output matrix

true for positive sequence(q0q1q2), false for inverted order(q2q1q0), default is false

nodeiter_start: the start NodeIter nodeiter_end: the end NodeIter

Returns:

target matrix include all the QGate's matrix (multiply)

pyqpanda.pyQPanda.get_unsupport_qgate_num(qprog: QProg, support_gates: List[List[str]]) int[源代码]

Count quantum program unsupported gate numner

Args:

qprog: quantum prog support_gates: support_gates

Returns:

unsupported gate numner

pyqpanda.pyQPanda.getstat(*args, **kwargs) Any[源代码]

Get the status of the Quantum machine

Args:

none

Returns:

the status of the Quantum machine, see QMachineStatus

Raises:

init_fail: An error occurred

pyqpanda.pyQPanda.iSWAP(first_qubit: Qubit, second_qubit: Qubit) QGate[源代码]
pyqpanda.pyQPanda.iSWAP(first_qubit_list: QVec, second_qubit_list: QVec) QCircuit
pyqpanda.pyQPanda.iSWAP(first_qubit_addr: int, second_qubit_addr: int) QGate
pyqpanda.pyQPanda.iSWAP(first_qubit_addr_list: List[int], second_qubit_addr_list: List[int]) QCircuit
pyqpanda.pyQPanda.iSWAP(first_qubit: Qubit, second_qubit: Qubit, theta_angle: float) QGate
pyqpanda.pyQPanda.iSWAP(first_qubit_list: QVec, second_qubit_list: QVec, theta_angle: float) QCircuit
pyqpanda.pyQPanda.iSWAP(first_qubit_addr: int, second_qubit_addr: int, theta_angle: float) QGate
pyqpanda.pyQPanda.iSWAP(first_qubit_addr_list: List[int], second_qubit_addr_list: List[int], theta_angle: float) QCircuit
Returns:

a iSWAP gate node

Raises:

run_fail: An error occurred in construct gate node

pyqpanda.pyQPanda.init(machine_type: QMachineType = QMachineType.CPU) bool[源代码]

Init the global unique quantum machine at background.

Args:

machine_type: quantum machine type, see pyQPanda.QMachineType

Returns:

bool: ture if initialization success

pyqpanda.pyQPanda.init_quantum_machine(machine_type: QMachineType = QMachineType.CPU) QuantumMachine[源代码]

Create and initialize a new quantum machine, and let it be global unique quantum machine

Args:

machine_type: quantum machine type, see pyQPanda.QMachineType

Returns:

the quantum machine, type is depend on machine_type QMachineType.CPU --> pyQPanda.CPUQVM QMachineType.CPU_SINGLE_THREAD --> pyQPanda.CPUSingleThreadQVM QMachineType.GPU --> pyQPanda.GPUQVM (if pyQPanda is build with GPU) QMachineType.NOISE --> pyQPanda.NoiseQVM return None if initial machine faild

Raises:

init_fail: An error occurred in init_quantum_machine

pyqpanda.pyQPanda.inverse(arg0: var) var[源代码]
pyqpanda.pyQPanda.isCarry(arg0: QVec, arg1: QVec, arg2: Qubit, arg3: Qubit) QCircuit[源代码]

Construct a circuit to determine if there is a carry

pyqpanda.pyQPanda.is_match_topology(gate: QGate, topo: List[List[float]]) bool[源代码]

Judge the QGate if match the target topologic structure of quantum circuit

Args:

gate: QGate topo: the target topologic structure of quantum circuit

Returns:

true if match, else false

pyqpanda.pyQPanda.is_supported_qgate_type(nodeitr: NodeIter) bool[源代码]

Judge if the target node is a QGate type

Args:

node_iter: node iter in qprog

Returns:

true ir false if the target node is a QGate type

pyqpanda.pyQPanda.is_swappable(prog: QProg, nodeitr_1: NodeIter, nodeitr_2: NodeIter) bool[源代码]

Judge the specialed two NodeIters in qprog whether can be exchanged

Args:

qprog: target quantum program node_iter1: node iter 1 in qprog node_iter2: node iter 2 in qprog

Returns:

true ir false for two NodeIters in qprog whether can be exchanged

pyqpanda.pyQPanda.iterative_amplitude_estimation(arg0: QCircuit, arg1: QVec, arg2: float, arg3: float) float[源代码]

estimate the probability corresponding to the ground state |1> of the last bit Args:

QCircuit: quantum circuit qvec: qubit list double: epsilon double: confidence

Returns:

result iterative amplitude

Raises:

run_fail: An error occurred in iterative_amplitude_estimation

pyqpanda.pyQPanda.ldd_decompose(qprog: QProg) QProg[源代码]

Decompose multiple control QGate

Args:

qprog: quantum program

Returns:

a new prog after decomposition

pyqpanda.pyQPanda.log(arg0: var) var[源代码]
pyqpanda.pyQPanda.matrix_decompose(qubits: QVec, matrix: numpy.ndarray[numpy.complex128[m, n]], mode: DecompositionMode = DecompositionMode.QSD, b_positive_seq: bool = True) QCircuit[源代码]
pyqpanda.pyQPanda.matrix_decompose(qubits: QVec, matrix: List[complex], mode: DecompositionMode = DecompositionMode.QSD, b_positive_seq: bool = True) QCircuit

Matrix decomposition

Args:

qubits: the used qubits matrix: The target matrix mode: DecompositionMode decomposition mode, default is QSD b_positive_seq: true for positive sequence(q0q1q2), false for inverted order(q2q1q0), default is true

Returns:

QCircuit The quantum circuit for target matrix

pyqpanda.pyQPanda.matrix_decompose_paulis(arg0: QuantumMachine, arg1: numpy.ndarray[numpy.float64[m, n]]) List[Tuple[float, QCircuit]][源代码]
pyqpanda.pyQPanda.matrix_decompose_paulis(arg0: QVec, arg1: numpy.ndarray[numpy.float64[m, n]]) List[Tuple[float, QCircuit]]

decompose matrix into paulis combination

Args:

quantum_machine: quantum machine matrix: 2^N *2^N double matrix

Returns:

result : linearcom contains pauli circuit

pyqpanda.pyQPanda.measure_all(qubit_list: QVec, cbit_list: List[ClassicalCondition]) QProg[源代码]
pyqpanda.pyQPanda.measure_all(qubit_addr_list: List[int], cbit_addr_list: List[int]) QProg

Create a list of measure node

Args:

qubit_list : measure qubits list cbit_list : cbits stores quantum measure result

Returns:

a list of measure node

pyqpanda.pyQPanda.mul(arg0: ClassicalCondition, arg1: ClassicalCondition) ClassicalCondition[源代码]
pyqpanda.pyQPanda.mul(arg0: ClassicalCondition, arg1: int) ClassicalCondition
pyqpanda.pyQPanda.mul(arg0: int, arg1: ClassicalCondition) ClassicalCondition
pyqpanda.pyQPanda.originir_to_qprog(file_path: str, machine: QuantumMachine) QProg[源代码]

Read OriginIR file and trans to QProg

Args:

file_path: OriginIR file path machine: initialized quantum machine

Returns:

Transformed QProgRaises: run_fail: An error occurred in originir_to_qprog

pyqpanda.pyQPanda.pauli_combination_replace(arg0: List[Tuple[float, QCircuit]], arg1: QuantumMachine, arg2: str, arg3: str) List[Tuple[float, QCircuit]][源代码]
pyqpanda.pyQPanda.planarity_testing(topo_data: List[List[int]]) bool[源代码]

planarity testing

Args:

topo_data: quantum program topo data

Returns:

result data

Raises:

run_fail: An error occurred in planarity_testing

pyqpanda.pyQPanda.pmeasure(qubit_list: QVec, select_max: int) List[Tuple[int, float]][源代码]

Get the probability distribution over qubits

Args:
qubit_list: qubit list to measure select_max: max returned element num in returnd tuple, should in [-1, 1<<len(qubit_list)]

default is -1, means no limit

Returns:

measure result of quantum machine in tuple form

pyqpanda.pyQPanda.pmeasure_no_index(qubit_list: QVec) List[float][源代码]

Get the probability distribution over qubits

Args:

qubit_list: qubit list to measure

Returns:

measure result of quantum machine in list form

pyqpanda.pyQPanda.poly(arg0: var, arg1: var) var[源代码]
pyqpanda.pyQPanda.print_matrix(matrix: List[complex], precision: int = 8) str[源代码]

Print matrix element

Args:

matrix: matrix precision: double value to string cutoff precision

Returns:

string of matrix

pyqpanda.pyQPanda.prob_run_dict(qprog: QProg, qubit_list: QVec, select_max: int = -1) Dict[str, float][源代码]

Run quantum program and get pmeasure result as dict

Args:

qprog: quantum program qubit_list: pmeasure qubits list select_max: max returned element num in returnd tuple, should in [-1, 1<<len(qubit_list)]

default is -1, means no limit

Returns:

measure result of quantum machine

Raises:

run_fail: An error occurred in measure quantum program

pyqpanda.pyQPanda.prob_run_list(qprog: QProg, qubit_list: QVec, select_max: int = -1) List[float][源代码]

Run quantum program and get pmeasure result as list

Args:

qprog: quantum program qubit_list: pmeasure qubits list select_max: max returned element num in returnd tuple, should in [-1, 1<<len(qubit_list)]

default is -1, means no limit

Returns:

measure result of quantum machine

Raises:

run_fail: An error occurred in measure quantum program

pyqpanda.pyQPanda.prob_run_tuple_list(qptog: QProg, qubit_list: QVec, select_max: int = -1) List[Tuple[int, float]][源代码]

Run quantum program and get pmeasure result as tuple list

Args:

qprog: quantum program qubit_list: pmeasure qubits list select_max: max returned element num in returnd tuple, should in [-1, 1<<len(qubit_list)]

default is -1, means no limit

Returns:

measure result of quantum machine

Raises:

run_fail: An error occurred in prob_run_tuple_list

pyqpanda.pyQPanda.prog_layer(*args, **kwargs) Any[源代码]
pyqpanda.pyQPanda.prog_to_dag(prog: QProg) QProgDAG[源代码]
pyqpanda.pyQPanda.qAlloc() Qubit[源代码]
pyqpanda.pyQPanda.qAlloc(qubit_addr: int) Qubit

Allocate a qubits After init()

Args:

qubit_addr: qubit physic address, should in [0,29)

Returns:

pyQPanda.Qubit: None, if qubit_addr error, or reached max number of allowed qubit

pyqpanda.pyQPanda.qAlloc_many(qubit_num: int) List[Qubit][源代码]

Allocate several qubits After init()

Args:

qubit_num: numbers of qubit want to be created

Returns:

list[pyQPanda.Qubit]: list of qubit

pyqpanda.pyQPanda.qFree(qubit: Qubit) None[源代码]

Free a qubit

Args:

Qubit: a qubit

Returns:

none

pyqpanda.pyQPanda.qFree_all() None[源代码]
pyqpanda.pyQPanda.qFree_all(qubit_list: QVec) None

Free a list of qubits

Args:

a list of qubits

Returns:

none

pyqpanda.pyQPanda.qop(VariationalQuantumCircuit: qop.VariationalQuantumCircuit, Hamiltonian, QuantumMachine: qop.QuantumMachine, qubitList: List[Qubit]) var[源代码]
pyqpanda.pyQPanda.qop(VariationalQuantumCircuit: qop.VariationalQuantumCircuit, Hamiltonian, QuantumMachine: qop.QuantumMachine, qubitList: Dict[int, Qubit]) var
pyqpanda.pyQPanda.qop_pmeasure(arg0: VariationalQuantumCircuit, arg1: List[int], arg2: QuantumMachine, arg3: List[Qubit]) var[源代码]
pyqpanda.pyQPanda.quantum_chip_adapter(qprog: QProg, machine: QuantumMachine, mapping: bool = True, config_file: str = 'QPandaConfig.json') list[源代码]

Quantum chip adaptive conversion

Args:

qprog: quantum program machine: quantum machine mapping: whether or not perform the mapping operation config_file: config file

Returns:

list contains qprog and qubit_list after mapping, if mapping is false, the qubit_list may be misoperated

pyqpanda.pyQPanda.quantum_walk_alg(*args, **kwargs) Any[源代码]

Build quantum-walk algorithm quantum circuit

Use Quantum-walk Algorithm to search target data, return QProg and search_result

Args:

list: data list Classical_condition: quantum Classical condition QuantumMachine: quantum machine repeat: search repeat times

Returns:

result : Quantum-walk search result

Raises:

run_fail: An error occurred in Quantum-walk

pyqpanda.pyQPanda.quick_measure(qubit_list: QVec, shots: int) Dict[str, int][源代码]

Quick measure

Args:

qubit_list: qubit list to measure shots: the repeat num of measure operate

Returns:

result of quantum programRaises: run_fail: An error occurred in measure quantum program

pyqpanda.pyQPanda.random_qcircuit(qvec: QVec, depth: int = 100, gate_type: List[str] = []) QCircuit[源代码]

Generate random quantum circuit

Args:

qubit_row: circuit qubit row value qubit_col: circuit qubit col value depth: circuit depth qvm: quantum machine qvec: out put circuits for random circuit

Returns:

random quantum program

Raises:

run_fail: An error occurred in generate random circuit

pyqpanda.pyQPanda.random_qprog(qubit_row: int, qubit_col: int, depth: int, qvm: QuantumMachine, qvec: QVec) QProg[源代码]

Generate random quantum program

Args:

qubit_row: circuit qubit row value qubit_col: circuit qubit col value depth: circuit depth qvm: quantum machine qvec: out put circuits for random qprog

Returns:

random quantum program

Raises:

run_fail: An error occurred in generate random qprog

pyqpanda.pyQPanda.recover_edges(topo_data: List[List[int]], max_connect_degree: int, candidate_edges: List[Tuple[int, List[int]]]) List[List[int]][源代码]

Recover edges from the candidate edges

Args:

topo_data: quantum program topo_data max_connect_degree: max value of connect degree candidate_edges: candidate edges

Returns:

topo data

Raises:

run_fail: An error occurred in recover_edges

pyqpanda.pyQPanda.remap(prog: QProg, target_qlist: QVec, target_clist: List[ClassicalCondition] = []) QProg[源代码]

Source qunatum program is mapped to the target qubits

Args:

prog: source quantum progprom target_qlist: target qubits target_clist: target cbits

Returns:

target quantum program

pyqpanda.pyQPanda.replace_complex_points(src_topo_data: List[List[int]], max_connect_degree: int, sub_topo_vec: List[Tuple[int, List[List[int]]]]) None[源代码]

Replacing complex points with subgraphs

Args:

src_topo_data: quantum program source topo data max_connect_degree: max value of connect degree sub_topo_vec: sub topo list

Returns:

none

Raises:

run_fail: An error occurred in replace_complex_points

pyqpanda.pyQPanda.run_with_configuration(program: QProg, cbit_list: List[ClassicalCondition], shots: int, noise_model: Noise = NoiseModel()) Dict[str, int][源代码]
pyqpanda.pyQPanda.run_with_configuration(program: QProg, shots: int, noise_model: Noise = NoiseModel()) Dict[str, int]

Run quantum program with configuration

Args:

program: quantum program cbit_list: classic cbits list shots: repeate run quantum program times noise_model: noise model, default is no noise. noise model only work on CPUQVM now

Returns:

result of quantum program execution in shots. first is the final qubit register state, second is it's hit shotRaises: run_fail: An error occurred in measure quantum program

pyqpanda.pyQPanda.sabre_mapping(prog: QProg, quantum_machine: QuantumMachine, init_map: List[int], max_look_ahead: int = 20, max_iterations: int = 10, config_data: str = 'QPandaConfig.json') QProg[源代码]
pyqpanda.pyQPanda.sabre_mapping(prog: QProg, quantum_machine: QuantumMachine, init_map: List[int], max_look_ahead: int, max_iterations: int, arch_matrix: numpy.ndarray[numpy.float64[m, n]]) QProg
pyqpanda.pyQPanda.sabre_mapping(prog: QProg, quantum_machine: QuantumMachine, max_look_ahead: int = 20, max_iterations: int = 10, config_data: str = 'QPandaConfig.json') QProg
pyqpanda.pyQPanda.sabre_mapping(prog: QProg, quantum_machine: QuantumMachine, max_look_ahead: int, max_iterations: int, arch_matrix: numpy.ndarray[numpy.float64[m, n]]) QProg

sabre mapping

Args:

prog: the target prog quantum_machine: quantum machine max_look_ahead: sabre_mapping max_look_ahead, default is 20 max_iterations: sabre_mapping max_iterations, default is 10 arch_matrix: arch matrix

Returns:

mapped quantum program

pyqpanda.pyQPanda.sigmoid(arg0: var) var[源代码]
pyqpanda.pyQPanda.sin(arg0: var) var[源代码]
pyqpanda.pyQPanda.single_qubit_rb(qvm: QuantumMachine, qubit: Qubit, clifford_range: List[int], num_circuits: int, shots: int, chip_id: int = 2, interleaved_gates: List[QGate] = []) Dict[int, float][源代码]
pyqpanda.pyQPanda.single_qubit_rb(config: QCloudTaskConfig, qubit: int, clifford_range: List[int], num_circuits: int, interleaved_gates: List[QGate] = []) Dict[int, float]

Single qubit rb with origin chip

Args:

config: quantum QCloudTaskConfig qubit: single qubit clifford_range: clifford range list num_circuits: the num of circuits interleaved_gates: interleaved gates list

Returns:

result data dict

Raises:

run_fail: An error occurred in single_qubit_rb

pyqpanda.pyQPanda.softmax(arg0: var) var[源代码]
pyqpanda.pyQPanda.split_complex_points(complex_points: List[int], max_connect_degree: int, topo_data: List[List[int]], split_method: ComplexVertexSplitMethod = ComplexVertexSplitMethod.LINEAR) List[Tuple[int, List[List[int]]]][源代码]

Splitting complex points into multiple points

Args:

topo_data: quantum program topo_data max_connect_degree: max value of connect degree complex_points: complex points list split_method: see ComplexVertexSplitMethod, default is ComplexVertexSplitMethod.LINEAR

Returns:

none

Raises:

run_fail: An error occurred in split_complex_points

pyqpanda.pyQPanda.stack(arg0: int, *args) var[源代码]
pyqpanda.pyQPanda.state_fidelity(state1: List[complex], state2: List[complex]) float[源代码]
pyqpanda.pyQPanda.state_fidelity(matrix1: List[List[complex]], matrix2: List[List[complex]]) float
pyqpanda.pyQPanda.state_fidelity(state1: List[complex], state2: List[List[complex]]) float
pyqpanda.pyQPanda.state_fidelity(state1: List[List[complex]], state2: List[complex]) float

compare two quantum states , Get the state fidelity

Args:

state1: quantum state matrix 1 state2: quantum state list 2

Returns:

state fidelity bewteen [0,1]

pyqpanda.pyQPanda.sub(arg0: ClassicalCondition, arg1: ClassicalCondition) ClassicalCondition[源代码]
pyqpanda.pyQPanda.sub(arg0: ClassicalCondition, arg1: int) ClassicalCondition
pyqpanda.pyQPanda.sub(arg0: int, arg1: ClassicalCondition) ClassicalCondition
pyqpanda.pyQPanda.sum(arg0: var) var[源代码]
pyqpanda.pyQPanda.tan(arg0: var) var[源代码]
pyqpanda.pyQPanda.to_Quil(qprog: QProg, machine: QuantumMachine) str[源代码]

Transform QProg to Quil instruction

Args:

qprog: QProg machine: quantum machine

Returns:

Quil instruction string

pyqpanda.pyQPanda.to_originir(qprog: QProg, machine: QuantumMachine) str[源代码]
pyqpanda.pyQPanda.to_originir(qprog: QCircuit, machine: QuantumMachine) str
pyqpanda.pyQPanda.to_originir(qprog: QGate, machine: QuantumMachine) str
pyqpanda.pyQPanda.to_originir(qprog: QIfProg, machine: QuantumMachine) str
pyqpanda.pyQPanda.to_originir(qprog: QWhileProg, machine: QuantumMachine) str
pyqpanda.pyQPanda.to_originir(qprog: QMeasure, machine: QuantumMachine) str

Transform QProg to OriginIR string

Args:

qprog: QProg or QCircute machine: quantum machine

Returns:

QriginIR string

pyqpanda.pyQPanda.topology_match(qprog: QProg, qubit_list: QVec, machine: QuantumMachine, confing_file: str = 'QPandaConfig.json') list[源代码]

Judge QProg/QCircuit matches the topology of the physical qubits

Args:

qprog: quantum prog qubit_list: qubits list in quantum prog machine: quantum machine confing_file: match configfilepath, default is QPandaConfig.json

Returns:

result data

Raises:

run_fail: An error occurred in topology_match

pyqpanda.pyQPanda.transform_binary_data_to_qprog(machine: QuantumMachine, data: List[int]) QProg[源代码]

Parse binary data trans to quantum program

Args:

machine: quantum machine data: list contains binary data from transform_qprog_to_binary()

Returns:

QProg

pyqpanda.pyQPanda.transform_originir_to_qprog(fname: str, machine: QuantumMachine) QProg[源代码]

Transform OriginIR to QProg

Args:

fname: file sotred OriginIR instruction machine: quantum machine

Returns:

QProg

pyqpanda.pyQPanda.transform_qprog_to_binary(qprog: QProg, machine: QuantumMachine) List[int][源代码]
pyqpanda.pyQPanda.transform_qprog_to_binary(qprog: QProg, machine: QuantumMachine, fname: str) None

Save quantum program to file as binary data

Args:

qprog: QProg machine: quantum machine fname: save to file name

pyqpanda.pyQPanda.transform_qprog_to_originir(qprog: QProg, machine: QuantumMachine) str[源代码]

Quantum program transform to OriginIR string

Args:

qprog: QProg machine: quantum machine

Returns:

OriginIR instruction string

pyqpanda.pyQPanda.transform_qprog_to_quil(qprog: QProg, machine: QuantumMachine) str[源代码]

Transform QProg to Quil instruction

Args:

qprog: QProg machine: quantum machine

Returns:

Quil instruction string

pyqpanda.pyQPanda.transform_to_base_qgate(qprog: QProg, machine: QuantumMachine, config_file: str = 'QPandaConfig.json') QProg[源代码]
pyqpanda.pyQPanda.transform_to_base_qgate(qprog: QProg, machine: QuantumMachine, convert_single_gates: List[str], convert_double_gates: List[str]) QProg

Basic quantum - gate conversion

Args:

qprog: quantum program machine: quantum machine convert_single_gates: quantum single gates sets convert_double_gates: quantum double gates sets

Returns:

a new prog after transform_to_base_qgate

pyqpanda.pyQPanda.transfrom_pauli_operator_to_matrix(arg0) List[complex][源代码]

transfrom pauli operator to matrix

Args:

matrix: 2^N *2^N double matrix

Returns:

result : hamiltonian

pyqpanda.pyQPanda.transpose(arg0: var) var[源代码]
pyqpanda.pyQPanda.validate_double_qgate_type(gate_str_list: List[str]) list[源代码]

Get valid QGates and valid double bit QGate type

Args:

double_gates: double gates list

Returns:

result list

pyqpanda.pyQPanda.validate_single_qgate_type(gate_str_list: List[str]) list[源代码]

Get valid QGates and valid single bit QGate type

Args:

single_gates: single gates list

Returns:

result list

pyqpanda.pyQPanda.vector_dot(x: List[float], y: List[float]) float[源代码]

Inner product of vector x and y

Args:

x: list x y: list y

Returns:

dot result

Raises:

run_fail: An error occurred in vector_dot

pyqpanda.pyQPanda.virtual_z_transform(prog: QProg, quantum_machine: QuantumMachine, b_del_rz_gate: bool = False, config_data: str = 'QPandaConfig.json') QProg[源代码]

virtual z transform

Args:

prog: the target prog quantum_machine: quantum machine b_del_rz_gate: whether delete the rz gate config_data: config data, @See JsonConfigParam::load_config()

Returns:

mapped quantum program

pyqpanda.utils

QPanda Utilities

Copyright (C) Origin Quantum 2017-2018

Licensed Under Apache Licence 2.0

Module Contents

Functions

single_gate_apply_to_all(gate, qubit_list)

Apply single gates to all qubits in qubit_list

single_gate(gate, qubit[, angle])

Apply a single gate to a qubit

meas_all(qubits, cbits)

Measure qubits mapping to cbits

get_fidelity(result, shots, target_result)

get quantum state fidelity

pyqpanda.utils.single_gate_apply_to_all(gate, qubit_list)[源代码]

Apply single gates to all qubits in qubit_list QGate(callback), list<Qubit> -> QCircuit

Args:

gate : the quantum gate need to apply to all qubits qubit_list : qubit list

Returns:

quantum circuit

pyqpanda.utils.single_gate(gate, qubit, angle=None)[源代码]

Apply a single gate to a qubit

Gate(callback), Qubit, angle(optional) -> QGate

Args:

gate : the quantum gate need to apply qubit qubit : single qubit angle : theta for rotation gate

Returns:

quantum circuit

Raises:

"

run_fail: An error occurred in construct single gate node

pyqpanda.utils.meas_all(qubits, cbits)[源代码]

Measure qubits mapping to cbits

list<Qubit>, list<CBit> -> QProg Args:

qubit_list : measure qubits list cbits_list : measure cbits list

Returns:

quantum prog

Raises:

run_fail: An error occurred in construct measure all node

pyqpanda.utils.get_fidelity(result, shots, target_result)[源代码]

get quantum state fidelity Args:

result : current quantum state shots : measure shots target_result : compared state

Returns:

fidelity bewteen [0,1]

Raises:

"

run_fail: An error occurred in get_fidelity

pyqpanda.Visualization

QPanda Python

Copyright (C) Origin Quantum 2017-2020

Licensed Under Apache Licence 2.0

Submodules

pyqpanda.Visualization.bloch

Bloch sphere

Module Contents
Classes

Bloch

Class for plotting data on the Bloch sphere. Valid data can be

class pyqpanda.Visualization.bloch.Bloch(fig=None, axes=None, view=None, figsize=None, background=False)[源代码]

Class for plotting data on the Bloch sphere. Valid data can be either points, vectors, or qobj objects. Attributes:

axes (instance):

User supplied Matplotlib axes for Bloch sphere animation.

fig (instance):

User supplied Matplotlib Figure instance for plotting Bloch sphere.

font_color (str):

Color of font used for Bloch sphere labels.

font_size (int):

Size of font used for Bloch sphere labels.

frame_alpha (float):

Sets transparency of Bloch sphere frame.

frame_color (str):

Color of sphere wireframe.

frame_width (int):

Width of wireframe.

point_color (list):

List of colors for Bloch sphere point markers to cycle through. i.e. By default, points 0 and 4 will both be blue ('b').

point_marker (list):

List of point marker shapes to cycle through.

point_size (list):

List of point marker sizes. Note, not all point markers look the same size when plotted!

sphere_alpha (float):

Transparency of Bloch sphere itself.

sphere_color (str):

Color of Bloch sphere.

figsize (list):

Figure size of Bloch sphere plot. Best to have both numbers the same; otherwise you will have a Bloch sphere that looks like a football.

vector_color (list):

List of vector colors to cycle through.

vector_width (int):

Width of displayed vectors.

vector_style (str):

Vector arrowhead style (from matplotlib's arrow style).

vector_mutation (int):

Width of vectors arrowhead.

view (list):

Azimuthal and Elevation viewing angles.

xlabel (list):

List of strings corresponding to +x and -x axes labels, respectively.

xlpos (list):

Positions of +x and -x labels respectively.

ylabel (list):

List of strings corresponding to +y and -y axes labels, respectively.

ylpos (list):

Positions of +y and -y labels respectively.

zlabel (list):

List of strings corresponding to +z and -z axes labels, respectively.

zlpos (list):

Positions of +z and -z labels respectively.

set_label_convention(convention)[源代码]

Set x, y and z labels according to one of conventions. Args:

convention (str):
One of the following:
  • "original"

  • "xyz"

  • "sx sy sz"

  • "01"

  • "polarization jones"

  • "polarization jones letters"

see also: http://en.wikipedia.org/wiki/Jones_calculus - "polarization stokes" see also: http://en.wikipedia.org/wiki/Stokes_parameters

Raises:

Exception: If convention is not valid.

clear()[源代码]

Resets Bloch sphere data sets to empty.

add_points(points, meth='s')[源代码]

Add a list of data points to Bloch sphere. Args:

points (array_like):

Collection of data points.

meth (str):

Type of points to plot, use 'm' for multicolored, 'l' for points connected with a line.

add_vectors(vectors)[源代码]

Add a list of vectors to Bloch sphere. Args:

vectors (array_like):

Array with vectors of unit length or smaller.

add_annotation(state_or_vector, text, **kwargs)[源代码]

Add a text or LaTeX annotation to Bloch sphere, parameterized by a qubit state or a vector. Args:

state_or_vector (array_like):

Position for the annotation. Qobj of a qubit or a vector of 3 elements.

text (str):

Annotation text. You can use LaTeX, but remember to use raw string e.g. r"$langle x rangle$" or escape backslashes e.g. "$\langle x \rangle$".

**kwargs:

Options as for mplot3d.axes3d.text, including: fontsize, color, horizontalalignment, verticalalignment.

Raises:

Exception: If input not array_like or tuple.

make_sphere()[源代码]

Plots Bloch sphere and data sets.

render(title='')[源代码]

Render the Bloch sphere and its data sets in on given figure and axes.

plot_back()[源代码]

back half of sphere

plot_front()[源代码]

front half of sphere

plot_axes()[源代码]

axes

plot_axes_labels()[源代码]

axes labels

plot_vectors()[源代码]

Plot vector

plot_points()[源代码]

Plot points

plot_annotations()[源代码]

Plot annotations

show(title='')[源代码]

Display Bloch sphere and corresponding data sets.

save(name=None, output='png', dirc=None)[源代码]

Saves Bloch sphere to file of type format in directory dirc. Args:

name (str):

Name of saved image. Must include path and format as well. i.e. '/Users/Paul/Desktop/bloch.png' This overrides the 'format' and 'dirc' arguments.

output (str):

Format of output image.

dirc (str):

Directory for output images. Defaults to current working directory.

pyqpanda.Visualization.bloch_plot

Module Contents
Classes

pauli

gate_node

PlotVector

Functions

count_pauli(i)

get_single_paulis(num_qubits, index)

plot_bloch_vector(bloch[, title, axis_obj, fig_size])

Draw a quantum state bloch view

plot_bloch_multivector(state[, title, fig_size])

Draw a quantum state bloch view

normalize(v[, tolerance])

bloch_plot_dict(frames_per_gate)

traversal_circuit(circuit)

plot_bloch_circuit(circuit[, trace, saveas, fps, ...])

Draw a quantum circuit bloch view , only support one qubit

pyqpanda.Visualization.bloch_plot.count_pauli(i)[源代码]
class pyqpanda.Visualization.bloch_plot.pauli(z, x)[源代码]

Bases: object

to_matrix()[源代码]
pyqpanda.Visualization.bloch_plot.get_single_paulis(num_qubits, index)[源代码]
pyqpanda.Visualization.bloch_plot.plot_bloch_vector(bloch, title='bloch', axis_obj=None, fig_size=None)[源代码]

Draw a quantum state bloch view

Args:

state : the quantum state title : the figure title fig_size : the figure size

Returns:

bloch figure shows quantum state

pyqpanda.Visualization.bloch_plot.plot_bloch_multivector(state, title='', fig_size=None)[源代码]

Draw a quantum state bloch view

Args:

state : the quantum state title : the figure title fig_size : the figure size

Returns:

bloch figure shows quantum state

pyqpanda.Visualization.bloch_plot.normalize(v, tolerance=1e-05)[源代码]
class pyqpanda.Visualization.bloch_plot.gate_node(name, theta)[源代码]

Bases: object

class pyqpanda.Visualization.bloch_plot.PlotVector[源代码]
static from_axisangle(theta, v)[源代码]
static from_value(value)[源代码]
get_conjugate()[源代码]
get_axisangle()[源代码]
tolist()[源代码]
vector_norm()[源代码]
pyqpanda.Visualization.bloch_plot.bloch_plot_dict(frames_per_gate)[源代码]
pyqpanda.Visualization.bloch_plot.traversal_circuit(circuit)[源代码]
pyqpanda.Visualization.bloch_plot.plot_bloch_circuit(circuit, trace=True, saveas=None, fps=20, secs_per_gate=1)[源代码]

Draw a quantum circuit bloch view , only support one qubit

Args:

circuit : the quantum circuit trace : whether shows the trace fps : flash fps

Returns:

bloch figure shows quantum circuit

pyqpanda.Visualization.circuit_composer

Module Contents
Classes

CircuitComposer

CircuitComposer for representing quantum circuit using ascii art.

class pyqpanda.Visualization.circuit_composer.CircuitComposer(n_qubits: int)[源代码]

Bases: pyqpanda.QCircuit

CircuitComposer for representing quantum circuit using ascii art.

Attributes
n_qubits: int

Number of qubits of quantum circuit.

circuit_layersList[List[str]]

List of each layer of quantum circuit, each layer of a list of string, representing each line of ascii art.

Examples
>>> n_qubits = 6
>>> qvm = pq.CPUQVM()
>>> qvm.init_qvm()
>>> q = qvm.qAlloc_many(n_qubits)
>>> circ1 = CircuitComposer(n_qubits)
>>> circuit = pq.QCircuit()
>>> circuit << pq.H(q[0]) << pq.CNOT(q[0], q[1]) << pq.CNOT(q[1], q[2])
>>> circ1.append(circuit)
>>> circ1 << pq.BARRIER(q)
>>> circ1.append(pq.QFT(q[4:]), "QFT")
>>> print(circ1)
           ┌─┐                    !
q_0:  |0>─ ┤H├ ───■── ──────  ────! ────────
           └─┘ ┌──┴─┐             !
q_1:  |0>─ ─── ┤CNOT├ ───■──  ────! ────────
               └────┘ ┌──┴─┐      !
q_2:  |0>─ ─── ────── ┤CNOT├  ────! ────────
                      └────┘      !
q_3:  |0>─ ─── ────── ──────  ────! ────────
                                  ! ┌──────┐
q_4:  |0>─ ─── ────── ──────  ────! ┤4     ├
                                  ! │  QFT │
q_5:  |0>─ ─── ────── ──────  ────! ┤5     ├
                                  ! └──────┘
>>> print(circ1.circuit)
          ┌─┐                   !
q_0:  |0>─┤H├ ───■── ────── ────! ─── ────────────── ─── ─
          └─┘ ┌──┴─┐            !
q_1:  |0>──── ┤CNOT├ ───■── ────! ─── ────────────── ─── ─
              └────┘ ┌──┴─┐     !
q_2:  |0>──── ────── ┤CNOT├ ────! ─── ────────────── ─── ─
                     └────┘     !
q_3:  |0>──── ────── ────── ────! ─── ────────────── ─── ─
                                !                    ┌─┐
q_4:  |0>──── ────── ────── ────! ─── ───────■────── ┤H├ X
                                ! ┌─┐ ┌──────┴─────┐ └─┘ │
q_5:  |0>──── ────── ────── ────! ┤H├ ┤CR(1.570796)├ ─── X
                                ! └─┘ └────────────┘
property circuit[源代码]

Return original quantum circuit representation.

append(circ: pyqpanda.QCircuit, name: str = '') None[源代码]

Append a quantum circuit.

Parameters
circpq.QCircuit

Quantum circuit to be appended.

namestr, optional

Name of the appended quantum circuit, by default None

Notes

If name is empty string, then append the circuit with its string representation not boxed.

The name must be in full English and cannot contain numbers or symbols

Even when a circuit is appended with a name, the composed circuit string can be get by using circuit property.

Examples
>>> circ = CircuitComposer(2)
>>> circuit = pq.QCircuit()
>>> circuit << pq.H(qubits[0]) << pq.CNOT(qubits[0], qubits[1])
>>> circ.append(circuit)
>>> print(circ)
           ┌─┐
q_0:  |0>─ ┤H├ ───■──
           └─┘ ┌──┴─┐
q_1:  |0>─ ─── ┤CNOT├
               └────┘
>>> circ.append(circuit, "GHZ")
>>> print(circ)
           ┌─┐        ┌──────┐
q_0:  |0>─ ┤H├ ───■── ┤0     ├
           └─┘ ┌──┴─┐ │  GHZ │
q_1:  |0>─ ─── ┤CNOT├ ┤1     ├
               └────┘ └──────┘
>>> print(circ.circuit)
          ┌─┐        ┌─┐
q_0:  |0>─┤H├ ───■── ┤H├ ───■──
          └─┘ ┌──┴─┐ └─┘ ┌──┴─┐
q_1:  |0>──── ┤CNOT├ ─── ┤CNOT├
              └────┘     └────┘
insert(circ: pyqpanda.QCircuit)[源代码]
draw_circuit(output=None, filename=None) str[源代码]

draw a quantum circuit.

Parameters

output : str,Output type: text、latex、pic

filenamestr, optional

When the output type is pic, this parameter can be used to specify the path to save the picture

Returns
str, if 'text' return ASII of circuit,

if 'latex' return latex of circuit, if 'pic' return picture save path of circuit,

Notes

If output is empty string, use text if filename is empty string,use 'QCircuit_pic.png'

pyqpanda.Visualization.circuit_draw

Module Contents
Functions

draw_circuit_pic(prog, pic_name[, scale, verbose, fold])

draw_qprog(prog[, output, scale, fold, filename, ...])

Draw a quantum circuit to different formats (set by output parameter):

show_prog_info_count(prog)

pyqpanda.Visualization.circuit_draw.draw_circuit_pic(prog, pic_name, scale=0.7, verbose=False, fold=30)[源代码]
pyqpanda.Visualization.circuit_draw.draw_qprog(prog, output=None, scale=0.7, fold=30, filename=None, with_logo=False, line_length=100, NodeIter_first=None, NodeIter_second=None, console_encode_type='utf8')[源代码]

Draw a quantum circuit to different formats (set by output parameter):

text: ASCII art TextDrawing that can be printed in the console. text: ASCII art TextDrawing that can be printed in the console.

pic: images with color rendered purely in Python.

latex: latex source code of circuit

Args:

prog : the quantum circuit to draw scale (float): scale of image to draw (shrink if < 1). Only used by the pic outputs. flod (int): x_max_size of image to draw. dOnly used by the pic outputs. Default is 30. filename (str): file path to save image to NodeIter_first: circuit printing start position. NodeIter_second: circuit printing end position. console_encode_type(str): Target console encoding type.

Mismatching of encoding types may result in character confusion, 'utf8' and 'gbk' are supported. Only used by the pic outputs.

line_length (int): Sets the length of the lines generated by text output type.

Returns:

no return

pyqpanda.Visualization.circuit_draw.show_prog_info_count(prog)[源代码]

pyqpanda.Visualization.circuit_info

Show quantum circuit info.

GateType:

PAULI_X_GATE, /**< Quantum pauli x gate / PAULI_Y_GATE, /**< Quantum pauli y gate */ PAULI_Z_GATE, /**< Quantum pauli z gate */ X_HALF_PI, /**< Quantum x half gate */ Y_HALF_PI, /**< Quantum y half gate */ Z_HALF_PI, /**< Quantum z half gate */ P_GATE, /**<Quantum p gate>/ HADAMARD_GATE, /**< Quantum hadamard gate / T_GATE, /**< Quantum t gate */ S_GATE, /**< Quantum s gate */ RX_GATE, /**< Quantum rotation x gate */ RY_GATE, /**< Quantum rotation y gate */ RZ_GATE, /**< Quantum rotation z gate */ RPHI_GATE, U1_GATE, /**< Quantum u1 gate */ U2_GATE, /**< Quantum u2 gate */ U3_GATE, /**< Quantum u3 gate */ U4_GATE, /**< Quantum u4 gate */ CU_GATE, /**< Quantum control-u gate */ CNOT_GATE, /**< Quantum control-not gate */ CZ_GATE, /**< Quantum control-z gate */ CP_GATE, /**<Quantum control-p gate>/ RYY_GATE, /**<Quantum ryy gate>*/ RXX_GATE, /**<Quantum rxx gate>*/ RZZ_GATE, /**<Quantum rzz gate>*/ RZX_GATE, /**<Quantum rzx gate>*/ CPHASE_GATE, /**< Quantum control-rotation gate */ ISWAP_THETA_GATE, /**< Quantum iswap-theta gate */ ISWAP_GATE, /**< Quantum iswap gate */ SQISWAP_GATE, /**< Quantum sqiswap gate */ SWAP_GATE, /**< Quantum swap gate */ TWO_QUBIT_GATE, /**< Quantum two-qubit gate */ TOFFOLI_GATE, ORACLE_GATE, CORACLE_GATE, I_GATE,

Module Contents
Functions

get_gate_name(gate_type)

get_circuit_info(→ None)

pyqpanda.Visualization.circuit_info.get_gate_name(gate_type: pyqpanda.GateType)[源代码]
pyqpanda.Visualization.circuit_info.get_circuit_info(circ: pyqpanda.QCircuit) None[源代码]

pyqpanda.Visualization.circuit_style

Module Contents
Classes

DefaultStyle

class pyqpanda.Visualization.circuit_style.DefaultStyle[源代码]
set_style(style_dic)[源代码]

pyqpanda.Visualization.draw_probability_map

Module Contents
Functions

draw_probaility(list)

Draw a quantum state probaility dict

draw_probability_dict(prob_dict)

Draw a quantum state probaility dict

pyqpanda.Visualization.draw_probability_map.draw_probaility(list)[源代码]

Draw a quantum state probaility dict

Args:

list : the quantum state probaility dict

Returns:

no return

pyqpanda.Visualization.draw_probability_map.draw_probability_dict(prob_dict)[源代码]

Draw a quantum state probaility dict

Args:

list : the quantum state probaility dict

Returns:

no return

pyqpanda.Visualization.exceptions

Exceptions for errors raised by PyQpanda.

Module Contents
exception pyqpanda.Visualization.exceptions.QError(*message)[源代码]

Bases: Exception

Base class for errors raised by PyQpanda.

exception pyqpanda.Visualization.exceptions.QIndexError(*message)[源代码]

Bases: QError, IndexError

Raised when a sequence subscript is out of range.

exception pyqpanda.Visualization.exceptions.QUserConfigError(*message)[源代码]

Bases: QError

Raised when an error is encountered reading a user config file.

message = 'User config invalid'[源代码]
exception pyqpanda.Visualization.exceptions.CircuitError(*message)[源代码]

Bases: QError

Base class for errors raised while processing a circuit.

pyqpanda.Visualization.matplotlib_draw

circuit visualization backend.

Module Contents
Classes

Anchor

MatplotlibDrawer

class pyqpanda.Visualization.matplotlib_draw.Anchor(reg_num, yind, fold)[源代码]
get_fold_info()[源代码]
set_fold_info(target_fold, fold_cnt)[源代码]
update_fold_info(index, gate_width, x_offset, layer_offset)[源代码]
plot_coord(index, gate_width, x_offset, layer_offset, last_h_pos)[源代码]
is_locatable(index, gate_width)[源代码]
set_index(index, gate_width)[源代码]
get_index()[源代码]
class pyqpanda.Visualization.matplotlib_draw.MatplotlibDrawer(qregs, cregs, ops, scale=1.0, style=None, plot_barriers=True, reverse_bits=False, layout=None, fold=25, ax=None)[源代码]
property ast[源代码]
layer_offset_recode = [][源代码]
if style:
if isinstance(style, dict):

self._style.set_style(style)

elif isinstance(style, str):
with open(style, 'r') as infile:

dic = json.load(infile)

self._style.set_style(dic)

get_op_color(op_name)[源代码]
set_multi_ctrl_bits(ctrl_state, num_ctrl_qubits, qbit, color_str)[源代码]
draw(filename=None, verbose=False)[源代码]
static param_parse(v)[源代码]
static format_numeric(val, tol=1e-05)[源代码]
static fraction(val, base=np.pi, n=100, tol=1e-05)[源代码]

pyqpanda.Visualization.parameterexpression

ParameterExpression Class to enable creating simple expressions of Parameters.

Module Contents
Classes

ParameterExpression

ParameterExpression class to enable creating expressions of Parameters.

class pyqpanda.Visualization.parameterexpression.ParameterExpression(symbol_map, expr)[源代码]

ParameterExpression class to enable creating expressions of Parameters.

property parameters[源代码]

Returns a set of the unbound Parameters in the expression.

bind(parameter_values)[源代码]

Binds the provided set of parameters to their corresponding values.

Args:
parameter_values (dict): Mapping of Parameter instances to the

numeric value to which they will be bound.

Raises:
CircuitError:
  • If parameter_values contains Parameters outside those in self.

  • If a non-numeric value is passed in parameter_values.

ZeroDivisionError:
  • If binding the provided values requires division by zero.

Returns:
ParameterExpression: a new expression parameterized by any parameters

which were not bound by parameter_values.

subs(parameter_map)[源代码]

Returns a new Expression with replacement Parameters.

Args:
parameter_map (dict): Mapping from Parameters in self to the

Parameter instances with which they should be replaced.

Raises:
CircuitError:
  • If parameter_map contains Parameters outside those in self.

  • If the replacement Parameters in parameter_map would result in a name conflict in the generated expression.

Returns:
ParameterExpression: a new expression with the specified parameters

replaced.

pyqpanda.Visualization.pi_check

Check if number close to values of PI

Module Contents
Functions

pi_check(inpt[, eps, output, ndigits])

Computes if a number is close to an integer

pyqpanda.Visualization.pi_check.pi_check(inpt, eps=1e-06, output='text', ndigits=5)[源代码]

Computes if a number is close to an integer fraction or multiple of PI and returns the corresponding string.

Args:

inpt (float): Number to check. eps (float): EPS to check against. output (str): Options are 'text' (default), 'OriginalIR'. ndigits (int): Number of digits to print

if returning raw inpt.

Returns:

str: string representation of output.

Raises:

QError: if output is not a valid option.

pyqpanda.Visualization.quantum_state_plot

Module Contents
Functions

config_colors(x, y, z, dx, dy, dz, color)

config_normals(polygons)

config_shade_colors(color, normals[, lightsource])

state_to_density_matrix(quantum_state)

convert quantum state to density matrix

complex_phase_cmap()

config_color_array(color)

plot_state_city(state[, title, figsize, color, ...])

plot quantum state city

plot_density_matrix(M[, xlabels, ylabels, title, ...])

plot quantum state density matrix

pyqpanda.Visualization.quantum_state_plot.config_colors(x, y, z, dx, dy, dz, color)[源代码]
pyqpanda.Visualization.quantum_state_plot.config_normals(polygons)[源代码]
pyqpanda.Visualization.quantum_state_plot.config_shade_colors(color, normals, lightsource=None)[源代码]
pyqpanda.Visualization.quantum_state_plot.state_to_density_matrix(quantum_state)[源代码]

convert quantum state to density matrix

Args:

quantum state: complex list

Returns:

density matrix

Raises:

RuntimeError: if input is not a valid quantum state.

pyqpanda.Visualization.quantum_state_plot.complex_phase_cmap()[源代码]
pyqpanda.Visualization.quantum_state_plot.config_color_array(color)[源代码]
pyqpanda.Visualization.quantum_state_plot.plot_state_city(state, title='', figsize=None, color=None, ax_real=None, ax_imag=None)[源代码]

plot quantum state city

Args:

quantum state: complex list title : string for figure color : color for figure

Returns:

matplot figure

Raises:

RuntimeError: if input is not a valid quantum state.

pyqpanda.Visualization.quantum_state_plot.plot_density_matrix(M, xlabels=None, ylabels=None, title=None, limits=None, phase_limits=None, fig=None, axis_vals=None, threshold=None)[源代码]

plot quantum state density matrix

Args:

quantum state: complex list title : string for figure color : color for figure

Returns:

matplot figure

Raises:

RuntimeError: if input is not a valid quantum state.

pyqpanda.Visualization.utils

Common visualization utilities.

Module Contents
Functions

matplotlib_close_if_inline(figure)

Close the given matplotlib figure if the backend in use draws figures inline.

pyqpanda.Visualization.utils.matplotlib_close_if_inline(figure)[源代码]

Close the given matplotlib figure if the backend in use draws figures inline. If the backend does not draw figures inline, this does nothing. This function is to prevent duplicate images appearing; the inline backends will capture the figure in preparation and display it as well, whereas the drawers want to return the figure to be displayed.

Package Contents

Functions

draw_qprog(prog[, output, scale, fold, filename, ...])

Draw a quantum circuit to different formats (set by output parameter):

show_prog_info_count(prog)

draw_probaility(list)

Draw a quantum state probaility dict

draw_probability_dict(prob_dict)

Draw a quantum state probaility dict

plot_state_city(state[, title, figsize, color, ...])

plot quantum state city

plot_density_matrix(M[, xlabels, ylabels, title, ...])

plot quantum state density matrix

state_to_density_matrix(quantum_state)

convert quantum state to density matrix

plot_bloch_circuit(circuit[, trace, saveas, fps, ...])

Draw a quantum circuit bloch view , only support one qubit

plot_bloch_vector(bloch[, title, axis_obj, fig_size])

Draw a quantum state bloch view

plot_bloch_multivector(state[, title, fig_size])

Draw a quantum state bloch view

pyqpanda.Visualization.draw_qprog(prog, output=None, scale=0.7, fold=30, filename=None, with_logo=False, line_length=100, NodeIter_first=None, NodeIter_second=None, console_encode_type='utf8')[源代码]

Draw a quantum circuit to different formats (set by output parameter):

text: ASCII art TextDrawing that can be printed in the console. text: ASCII art TextDrawing that can be printed in the console.

pic: images with color rendered purely in Python.

latex: latex source code of circuit

Args:

prog : the quantum circuit to draw scale (float): scale of image to draw (shrink if < 1). Only used by the pic outputs. flod (int): x_max_size of image to draw. dOnly used by the pic outputs. Default is 30. filename (str): file path to save image to NodeIter_first: circuit printing start position. NodeIter_second: circuit printing end position. console_encode_type(str): Target console encoding type.

Mismatching of encoding types may result in character confusion, 'utf8' and 'gbk' are supported. Only used by the pic outputs.

line_length (int): Sets the length of the lines generated by text output type.

Returns:

no return

pyqpanda.Visualization.show_prog_info_count(prog)[源代码]
pyqpanda.Visualization.draw_probaility(list)[源代码]

Draw a quantum state probaility dict

Args:

list : the quantum state probaility dict

Returns:

no return

pyqpanda.Visualization.draw_probability_dict(prob_dict)[源代码]

Draw a quantum state probaility dict

Args:

list : the quantum state probaility dict

Returns:

no return

pyqpanda.Visualization.plot_state_city(state, title='', figsize=None, color=None, ax_real=None, ax_imag=None)[源代码]

plot quantum state city

Args:

quantum state: complex list title : string for figure color : color for figure

Returns:

matplot figure

Raises:

RuntimeError: if input is not a valid quantum state.

pyqpanda.Visualization.plot_density_matrix(M, xlabels=None, ylabels=None, title=None, limits=None, phase_limits=None, fig=None, axis_vals=None, threshold=None)[源代码]

plot quantum state density matrix

Args:

quantum state: complex list title : string for figure color : color for figure

Returns:

matplot figure

Raises:

RuntimeError: if input is not a valid quantum state.

pyqpanda.Visualization.state_to_density_matrix(quantum_state)[源代码]

convert quantum state to density matrix

Args:

quantum state: complex list

Returns:

density matrix

Raises:

RuntimeError: if input is not a valid quantum state.

pyqpanda.Visualization.plot_bloch_circuit(circuit, trace=True, saveas=None, fps=20, secs_per_gate=1)[源代码]

Draw a quantum circuit bloch view , only support one qubit

Args:

circuit : the quantum circuit trace : whether shows the trace fps : flash fps

Returns:

bloch figure shows quantum circuit

pyqpanda.Visualization.plot_bloch_vector(bloch, title='bloch', axis_obj=None, fig_size=None)[源代码]

Draw a quantum state bloch view

Args:

state : the quantum state title : the figure title fig_size : the figure size

Returns:

bloch figure shows quantum state

pyqpanda.Visualization.plot_bloch_multivector(state, title='', fig_size=None)[源代码]

Draw a quantum state bloch view

Args:

state : the quantum state title : the figure title fig_size : the figure size

Returns:

bloch figure shows quantum state