使用pyqpanda3量子机器学习模块 ################################# .. warning:: 以下接口的量子计算部分使用pyqpanda3 https://qcloud.originqc.com.cn/document/qpanda-3/index.html。 量子计算层 *********************************** .. _QuantumLayer_pq3: QuantumLayer ============================ 如您熟悉pyqpanda3语法,可以使用该接口QuantumLayer,自定义pyqpanda3模拟器进行计算。 .. py:class:: pyvqnet.qnn.pq3.quantumlayer.QuantumLayer(qprog_with_measure,para_num,diff_method:str = "parameter_shift",delta:float = 0.01,dtype=None,name="") 变分量子层的抽象计算模块。对一个参数化的量子线路使用pyqpanda3进行仿真,得到测量结果。该变分量子层继承了VQNet框架的梯度计算模块,可以使用参数漂移法等计算线路参数的梯度,训练变分量子线路模型或将变分量子线路嵌入混合量子和经典模型。 :param qprog_with_measure: 用pyQPand构建的量子线路运行和测量函数。 :param para_num: `int` - 参数个数。 :param diff_method: 求解量子线路参数梯度的方法,“参数位移”或“有限差分”,默认参数偏移。 :param delta: 有限差分计算梯度时的 \delta。 :param dtype: 参数的数据类型,defaults:None,使用默认数据类型:kfloat32,代表32位浮点数。 :param name: 这个模块的名字, 默认为""。 :return: 一个可以计算量子线路的模块。 .. note:: qprog_with_measure是pyQPanda中定义的量子线路函数 :https://qcloud.originqc.com.cn/document/qpanda-3/dc/d12/tutorial_quantum_program.html。 此函数必须包含输入和参数两个参数作为函数入参(即使某个参数未实际使用),输出为线路的测量结果或者期望值(需要为np.ndarray或包含数值的列表),否则无法在QpandaQCircuitVQCLayerLite中正常运行。 量子线路函数 qprog_with_measure (input,param)的使用可参考下面的例子。 `input`: 输入一维经典数据。如果没有,输入 None。 `param`: 输入一维的变分量子线路的待训练参数。 .. note:: 该类具有别名 `QuantumLayerV2`, `QpandaQCircuitVQCLayerLite`。 .. note:: 该类计算梯度需要额外使用pyqpanda3进行线路计算个数与参数个数、数据个数、数据维度的乘积线性相关。 Example:: from pyvqnet.qnn.pq3.measure import ProbsMeasure from pyvqnet.qnn.pq3.quantumlayer import QuantumLayer from pyvqnet.tensor import QTensor,ones import pyqpanda3.core as pq def pqctest (input,param): num_of_qubits = 4 m_machine = pq.CPUQVM() qubits = range(num_of_qubits) circuit = pq.QCircuit() circuit<`_ 。 :param input_channels: `int` - 输入通道数。 :param output_channels: `int` - 输出通道数。 :param quantum_number: `int` - 单个内核的大小。 :param stride: `tuple` - 步长,默认为(1,1)。 :param padding: `tuple` - 填充,默认为(0,0)。 :param kernel_initializer: `callable` - 默认为正态分布。 :param machine: `str` - 使用的虚拟机,默认使用CPU模拟。 :param dtype: 参数的数据类型,defaults:None,使用默认数据类型:kfloat32,代表32位浮点数。 :param name: 这个模块的名字, 默认为""。 :return: 量子卷积层。 Example:: from pyvqnet.tensor import tensor from pyvqnet.qnn.qcnn.qconv import QConv x = tensor.ones([1,3,4,4]) layer = QConv(input_channels=3, output_channels=2, quantum_number=4, stride=(2, 2)) y = layer(x) print(y) # [ # [[[-0.0889078, -0.0889078], # [-0.0889078, -0.0889078]], # [[0.7992646, 0.7992646], # [0.7992646, 0.7992646]]] # ] 量子逻辑门 *********************************** 处理量子比特的方式就是量子逻辑门。 使用量子逻辑门,我们有意识的使量子态发生演化。量子逻辑门是构成量子算法的基础。 基本量子逻辑门 ============================ 在VQNet中,我们使用本源量子自研的 `pyqpanda3 `_ 的各个逻辑门搭建量子线路,进行量子模拟。 当前pyQPanda支持的逻辑门可参考pyqpanda3 `量子逻辑门 `_ 部分的定义。 此外VQNet还封装了部分在量子机器学习中常用的量子逻辑门组合: .. _pq3_gate: BasicEmbeddingCircuit ============================ .. py:function:: pyvqnet.qnn.pq3.template.BasicEmbeddingCircuit(input_feat,qlist) 将n个二进制特征编码为n个量子比特的基态。 例如, 对于 ``features=([0, 1, 1])``, 在量子系统下其基态为 :math:`|011 \rangle`。 :param input_feat: ``(n)`` 大小的二进制输入。 :param qlist: 构建该模板线路量子比特。 :return: 量子线路。 Example:: from pyvqnet.qnn.pq3.template import BasicEmbeddingCircuit import pyqpanda3.core as pq from pyvqnet import tensor input_feat = tensor.QTensor([1,1,0]) qlist = range(3) circuit = BasicEmbeddingCircuit(input_feat,qlist) print(circuit) AngleEmbeddingCircuit ============================ .. py:function:: pyvqnet.qnn.pq3.template.AngleEmbeddingCircuit(input_feat,qubits,rotation:str='X') 将 :math:`N` 特征编码到 :math:`n` 量子比特的旋转角度中, 其中 :math:`N \leq n`。 旋转可以选择为 : 'X' , 'Y' , 'Z', 如 ``rotation`` 的参数定义为: * ``rotation='X'`` 将特征用作RX旋转的角度。 * ``rotation='Y'`` 将特征用作RY旋转的角度。 * ``rotation='Z'`` 将特征用作RZ旋转的角度。 ``features`` 的长度必须小于或等于量子比特的数量。如果 ``features`` 中的长度少于量子比特,则线路不应用剩余的旋转门。 :param input_feat: 表示参数的numpy数组。 :param qubits: 量子比特索引。 :param rotation: 使用什么旋转,默认为“X”。 :return: 量子线路。 Example:: from pyvqnet.qnn.pq3.template import AngleEmbeddingCircuit import numpy as np m_qlist = range(2) input_feat = np.array([2.2, 1]) C = AngleEmbeddingCircuit(input_feat,m_qlist,'X') print(C) C = AngleEmbeddingCircuit(input_feat,m_qlist,'Y') print(C) C = AngleEmbeddingCircuit(input_feat,m_qlist,'Z') print(C) IQPEmbeddingCircuits ============================ .. py:function:: pyvqnet.qnn.pq3.template.IQPEmbeddingCircuits(input_feat,qubits,rep:int = 1) 使用IQP线路的对角门将 :math:`n` 特征编码为 :math:`n` 量子比特。 编码是由 `Havlicek et al. (2018) `_ 提出。 通过指定 ``n_repeats`` ,可以重复基本IQP线路。 :param input_feat: 表示参数的numpy数组。 :param qubits: 量子比特索引列表。 :param rep: 重复量子线路块,默认次数1。 :return: 量子线路。 Example:: import numpy as np from pyvqnet.qnn.pq3.template import IQPEmbeddingCircuits input_feat = np.arange(1,100) qlist = range(3) circuit = IQPEmbeddingCircuits(input_feat,qlist,rep = 3) print(circuit) RotCircuit ============================ .. py:function:: pyvqnet.qnn.pq3.template.RotCircuit(para,qubits) 任意单量子比特旋转。qlist的数量应该是1,参数的数量应该是3。 .. math:: R(\phi,\theta,\omega) = RZ(\omega)RY(\theta)RZ(\phi)= \begin{bmatrix} e^{-i(\phi+\omega)/2}\cos(\theta/2) & -e^{i(\phi-\omega)/2}\sin(\theta/2) \\ e^{-i(\phi-\omega)/2}\sin(\theta/2) & e^{i(\phi+\omega)/2}\cos(\theta/2) \end{bmatrix}. :param para: 表示参数 :math:`[\phi, \theta, \omega]` 的numpy数组。 :param qubits: 量子比特索引,只接受单个量子比特。 :return: 量子线路。 Example:: from pyvqnet.qnn.pq3.template import RotCircuit import pyqpanda3.core as pq from pyvqnet import tensor m_qlist = 1 param =tensor.QTensor([3,4,5]) c = RotCircuit(param,m_qlist) print(c) CRotCircuit ============================ .. py:function:: pyvqnet.qnn.pq3.template.CRotCircuit(para,control_qubits,rot_qubits) 受控Rot操作符。 .. math:: CR(\phi, \theta, \omega) = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0\\ 0 & 0 & e^{-i(\phi+\omega)/2}\cos(\theta/2) & -e^{i(\phi-\omega)/2}\sin(\theta/2)\\ 0 & 0 & e^{-i(\phi-\omega)/2}\sin(\theta/2) & e^{i(\phi+\omega)/2}\cos(\theta/2) \end{bmatrix}. :param para: 表示参数 :math:`[\phi, \theta, \omega]` 的numpy数组。 :param control_qubits: 量子比特索引,量子比特的数量应为1。 :param rot_qubits: Rot量子比特索引,量子比特的数量应为1。 :return: 量子线路。 Example:: from pyvqnet.qnn.pq3.template import CRotCircuit import pyqpanda3.core as pq import numpy as np m_qlist = range(1) control_qlist = [1] param = np.array([3,4,5]) cir = CRotCircuit(param,control_qlist,m_qlist) print(cir) CSWAPcircuit ============================ .. py:function:: pyvqnet.qnn.pq3.template.CSWAPcircuit(qubits) 受控SWAP线路。 .. math:: CSWAP = \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 & 0 & 1 & 0 \\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \end{bmatrix}. .. note:: 提供的第一个量子比特对应于 **control qubit** 。 :param qubits: 量子比特索引列表第一个量子比特是控制量子比特。qlist的长度必须为3。 :return: 量子线路。 Example:: from pyvqnet.qnn.pq3 import CSWAPcircuit import pyqpanda3.core as pq m_machine = pq.CPUQVM() m_qlist = range(3) c =CSWAPcircuit([m_qlist[1],m_qlist[2],m_qlist[0]]) print(c) Controlled_Hadamard ======================= .. py:function:: pyvqnet.qnn.pq3.template.Controlled_Hadamard(qubits) 受控Hadamard逻辑门 .. math:: CH = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & \frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}} \\ 0 & 0 & \frac{1}{\sqrt{2}} & -\frac{1}{\sqrt{2}} \end{bmatrix}. :param qubits: 量子比特索引。 Examples:: import pyqpanda3.core as pq machine = pq.CPUQVM() qubits =range(2) from pyvqnet.qnn.pq3 import Controlled_Hadamard cir = Controlled_Hadamard(qubits) print(cir) CCZ ============== .. py:function:: pyvqnet.qnn.pq3.template.CCZ(qubits) 受控-受控-Z (controlled-controlled-Z) 逻辑门。 .. math:: CCZ = \begin{pmatrix} 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 & 1 & 0\\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 \end{pmatrix} :param qubits: 量子比特索引。 :return: pyqpanda QCircuit Example:: import pyqpanda3.core as pq machine = pq.CPUQVM() qubits = range(3) from pyvqnet.qnn.pq3 import CCZ cir = CCZ(qubits) FermionicSingleExcitation ============================ .. py:function:: pyvqnet.qnn.pq3.template.FermionicSingleExcitation(weight, wires, qubits) 对泡利矩阵的张量积求幂的耦合簇单激励算子。矩阵形式下式给出: .. math:: \hat{U}_{pr}(\theta) = \mathrm{exp} \{ \theta_{pr} (\hat{c}_p^\dagger \hat{c}_r -\mathrm{H.c.}) \}, :param weight: 量子比特 p 上的变参. :param wires: 表示区间[r, p]中的量子比特索引子集。最小长度必须为2。第一索引值被解释为r,最后一个索引值被解释为p。 中间的索引被CNOT门作用,以计算量子位集的奇偶校验。 :param qubits: 量子比特索引。 :return: pyqpanda QCircuit Examples:: from pyvqnet.qnn.pq3 import FermionicSingleExcitation, expval weight = 0.5 import pyqpanda3.core as pq machine = pq.CPUQVM() qlists = range(3) cir = FermionicSingleExcitation(weight, [1, 0, 2], qlists) FermionicDoubleExcitation ============================ .. py:function:: pyvqnet.qnn.pq3.template.FermionicDoubleExcitation(weight, wires1, wires2, qubits) 对泡利矩阵的张量积求幂的耦合聚类双激励算子,矩阵形式由下式给出: .. math:: \hat{U}_{pqrs}(\theta) = \mathrm{exp} \{ \theta (\hat{c}_p^\dagger \hat{c}_q^\dagger \hat{c}_r \hat{c}_s - \mathrm{H.c.}) \}, 其中 :math:`\hat{c}` 和 :math:`\hat{c}^\dagger` 是费米子湮灭和 创建运算符和索引 :math:`r, s` 和 :math:`p, q` 在占用的和 分别为空分子轨道。 使用 `Jordan-Wigner 变换 `_ 上面定义的费米子算子可以写成 根据 Pauli 矩阵(有关更多详细信息,请参见 `arXiv:1805.04340 `_) .. math:: \hat{U}_{pqrs}(\theta) = \mathrm{exp} \Big\{ \frac{i\theta}{8} \bigotimes_{b=s+1}^{r-1} \hat{Z}_b \bigotimes_{a=q+1}^{p-1} \hat{Z}_a (\hat{X}_s \hat{X}_r \hat{Y}_q \hat{X}_p + \hat{Y}_s \hat{X}_r \hat{Y}_q \hat{Y}_p +\\ \hat{X}_s \hat{Y}_r \hat{Y}_q \hat{Y}_p + \hat{X}_s \hat{X}_r \hat{X}_q \hat{Y}_p - \mathrm{H.c.} ) \Big\} :param weight: 可变参数 :param wires1: 代表的量子比特的索引列表区间 [s, r] 中占据量子比特的子集。第一个索引被解释为 s,最后一索引被解释为 r。 CNOT 门对中间的索引进行操作,以计算一组量子位的奇偶性。 :param wires2: 代表的量子比特的索引列表区间 [q, p] 中占据量子比特的子集。第一根索引被解释为 q,最后一索引被解释为 p。 CNOT 门对中间的索引进行操作,以计算一组量子位的奇偶性。 :param qubits: 量子比特索引。 :return: pyqpanda QCircuit Examples:: import pyqpanda3.core as pq from pyvqnet.qnn.pq3 import FermionicDoubleExcitation, expval machine = pq.CPUQVM() qlists = range(5) weight = 1.5 cir = FermionicDoubleExcitation(weight, wires1=[0, 1], wires2=[2, 3, 4], qubits=qlists) UCCSD ================== .. py:function:: pyvqnet.qnn.pq3.template.UCCSD(weights, wires, s_wires, d_wires, init_state, qubits) 实现酉耦合簇单激发和双激发拟设(UCCSD)。UCCSD 是 VQE 拟设,通常用于运行量子化学模拟。 在一阶 Trotter 近似内,UCCSD 酉函数由下式给出: .. math:: \hat{U}(\vec{\theta}) = \prod_{p > r} \mathrm{exp} \Big\{\theta_{pr} (\hat{c}_p^\dagger \hat{c}_r-\mathrm{H.c.}) \Big\} \prod_{p > q > r > s} \mathrm{exp} \Big\{\theta_{pqrs} (\hat{c}_p^\dagger \hat{c}_q^\dagger \hat{c}_r \hat{c}_s-\mathrm{H.c.}) \Big\} 其中 :math:`\hat{c}` 和 :math:`\hat{c}^\dagger` 是费米子湮灭和 创建运算符和索引 :math:`r, s` 和 :math:`p, q` 在占用的和 分别为空分子轨道。(更多细节见 `arXiv:1805.04340 `_): :param weights: 包含参数的大小 ``(len(s_wires)+ len(d_wires))`` 张量 :math:`\theta_{pr}` 和 :math:`\theta_{pqrs}` 输入 Z 旋转 ``FermionicSingleExcitation`` 和 ``FermionicDoubleExcitation`` 。 :param wires: 模板作用的量子比特索引 :param s_wires: 包含量子比特索引的列表序列 ``[r,...,p]`` 由单一激发产生 :math:`\vert r, p \rangle = \hat{c}_p^\dagger \hat{c}_r \vert \mathrm{HF} \rangle`, 其中 :math:`\vert \mathrm{HF} \rangle` 表示 Hartee-Fock 参考态。 :param d_wires: 列表序列,每个列表包含两个列表 指定索引 ``[s, ...,r]`` 和 ``[q,..., p]`` 定义双激励 :math:`\vert s, r, q, p \rangle = \hat{c}_p^\dagger \hat{c}_q^\dagger \hat{c}_r\hat{c}_s \vert \mathrm{HF} \rangle` 。 :param init_state: 长度 ``len(wires)`` occupation-number vector 表示 高频状态。 ``init_state`` 在量子比特初始化状态。 :param qubits: 量子比特索引。 Examples:: import pyqpanda3.core as pq from pyvqnet.tensor import tensor from pyvqnet.qnn.pq3 import UCCSD, expval machine = pq.CPUQVM() qlists = range(6) weight = tensor.zeros([8]) cir = UCCSD(weight,wires = [0,1,2,3,4,5,6], s_wires=[[0, 1, 2], [0, 1, 2, 3, 4], [1, 2, 3], [1, 2, 3, 4, 5]], d_wires=[[[0, 1], [2, 3]], [[0, 1], [2, 3, 4, 5]], [[0, 1], [3, 4]], [[0, 1], [4, 5]]], init_state=[1, 1, 0, 0, 0, 0], qubits=qlists) QuantumPoolingCircuit ============================ .. py:function:: pyvqnet.qnn.pq3.template.QuantumPoolingCircuit(sources_wires, sinks_wires, params,qubits) 对数据进行降采样的量子电路。 为了减少电路中的量子位数量,首先在系统中创建成对的量子位。在最初配对所有量子位之后,将广义2量子位酉元应用于每一对量子位上。并在应用这两个量子位酉元之后,在神经网络的其余部分忽略每对量子位中的一个量子位。 :param sources_wires: 将被忽略的源量子位索引。 :param sinks_wires: 将保留的目标量子位索引。 :param params: 输入参数。 :param qubits: 量子比特索引。 :return: pyqpanda QCircuit Examples:: from pyvqnet.qnn.pq3.template import QuantumPoolingCircuit import pyqpanda3.core as pq from pyvqnet import tensor qlists = range(4) p = tensor.full([6], 0.35) cir = QuantumPoolingCircuit([0, 1], [2, 3], p, qlists) print(cir) 常用量子线路组合 *********************************** VQNet提供了量子机器学习研究中常用的一些量子线路 HardwareEfficientAnsatz ============================ .. py:class:: pyvqnet.qnn.pq3.ansatz.HardwareEfficientAnsatz(qubits,single_rot_gate_list,entangle_gate="CNOT",entangle_rules='linear',depth=1) 论文介绍的Hardware Efficient Ansatz的实现: `Hardware-efficient Variational Quantum Eigensolver for Small Molecules `__ 。 通过其成员函数 ``create_ansatz`` 返回 `pyqpanda3` 的量子线路。 :param qubits: 量子比特索引。 :param single_rot_gate_list: 单个量子位旋转门列表由一个或多个作用于每个量子位的旋转门构成。目前支持 Rx、Ry、Rz。 :param entangle_gate: 非参数化纠缠门。支持CNOT、CZ。默认: CNOT。 :param entangle_rules: 电路中如何使用纠缠门。 ``linear`` 意味着纠缠门将作用于每个相邻的量子位。 ``all`` 意味着纠缠门将作用于任何两个 qbuits。 默认值:``linear``。 :param depth: ansatz 的深度,默认:1。 Example:: import pyqpanda3.core as pq from pyvqnet.tensor import QTensor,tensor from pyvqnet.qnn.pq3.ansatz import HardwareEfficientAnsatz machine = pq.CPUQVM() qlist = range(4) c = HardwareEfficientAnsatz(qlist,["rx", "RY", "rz"], entangle_gate="cnot", entangle_rules="linear", depth=1) w = tensor.ones([c.get_para_num()]) cir = c.create_ansatz(w) print(cir) BasicEntanglerTemplate ============================ .. py:class:: pyvqnet.qnn.pq3.template.BasicEntanglerTemplate(weights=None, num_qubits=1, rotation=pyqpanda.RX) 由每个量子位上的单参数单量子位旋转组成的层,后跟一个闭合链或环组合的多个CNOT 门。 CNOT 门环将每个量子位与其邻居连接起来,最后一个量子位被认为是第一个量子位的邻居。 层数 :math:`L` 由参数 ``weights`` 的第一个维度决定。 通过其成员函数 ``create_circuit`` 返回 `pyqpanda3` 的量子线路。 :param weights: 形状的权重张量 `(L, len(qubits))`。 每个权重都用作量子含参门中的参数。默认值为: ``None`` ,则使用 `(1,1)` 正态分布随机数作为权重。 :param num_qubits: 量子比特数,默认为1。 :param rotation: 使用单参数单量子比特门,``pyqpanda.RX`` 被用作默认值。 Example:: import pyqpanda3.core as pq import numpy as np from pyvqnet.qnn.pq3 import BasicEntanglerTemplate np.random.seed(42) num_qubits = 5 shape = [1, num_qubits] weights = np.random.random(size=shape) machine = pq.CPUQVM() qubits = range(num_qubits) circuit = BasicEntanglerTemplate(weights=weights, num_qubits=num_qubits, rotation=pq.RZ) result = circuit.compute_circuit() cir = circuit.create_circuit(qubits) circuit.print_circuit(qubits) StronglyEntanglingTemplate ============================ .. py:class:: pyvqnet.qnn.pq3.template.StronglyEntanglingTemplate(weights=None, num_qubits=1, ranges=None) 由单个量子比特旋转和纠缠器组成的层,参考 `circuit-centric classifier design `__ . 参数 ``weights`` 包含每一层的权重。 因此得出层数 :math:`L` 等于 ``weights`` 的第一个维度。 其包含2-qubit CNOT 门,作用于 :math:`M` 个量子比特上,:math:`i = 1,...,M`。 每个门的第二个量子位标号由公式 :math:`(i+r)\mod M` 给出,其中 :math:`r` 是一个称为 ``range`` 的超参数,并且 :math:`0 < r < M`。 通过其成员函数 ``create_circuit`` 返回 `pyqpanda3` 的量子线路。 :param weights: 形状为 ``(L, M, 3)`` 的权重张量,默认值:None,使用形状为 ``(1,1,3)`` 的随机张量。 :param num_qubits: 量子比特数,默认值:1。 :param ranges: 确定每个后续层的范围超参数的序列; 默认值:None,使用 :math:`r=l \ mod M` 作为ranges 的值。 Example:: from pyvqnet.qnn.pq3 import StronglyEntanglingTemplate import pyqpanda3.core as pq from pyvqnet.tensor import * import numpy as np np.random.seed(42) num_qubits = 3 shape = [2, num_qubits, 3] weights = np.random.random(size=shape) machine = pq.CPUQVM() qubits = range(num_qubits) circuit = StronglyEntanglingTemplate(weights, num_qubits=num_qubits ) result = circuit.compute_circuit() cir = circuit.create_circuit(qubits) circuit.print_circuit(qubits) ComplexEntangelingTemplate ============================ .. py:class:: pyvqnet.qnn.pq3.ComplexEntangelingTemplate(weights,num_qubits,depth) 由 U3 门和 CNOT 门组成的强纠缠层。 此线路模板来自以下论文:https://arxiv.org/abs/1804.00633。 通过其成员函数 ``create_circuit`` 返回 `pyqpanda3` 的量子线路。 :param weights: 参数,[depth,num_qubits,3]的形状 :param num_qubits: 量子比特数。 :param depth: 子电路的深度。 Example:: from pyvqnet.qnn.pq3 import ComplexEntangelingTemplate import pyqpanda3.core as pq from pyvqnet.tensor import * depth =3 num_qubits = 8 shape = [depth, num_qubits, 3] weights = tensor.randn(shape) machine = pq.CPUQVM() qubits = range(num_qubits) circuit = ComplexEntangelingTemplate(weights, num_qubits=num_qubits,depth=depth) result = circuit.create_circuit(qubits) circuit.print_circuit(qubits) Quantum_Embedding ============================ .. py:class:: pyvqnet.qnn.pq3.Quantum_Embedding(qubits, machine, num_repetitions_input, depth_input, num_unitary_layers, num_repetitions) 使用 RZ,RY,RZ 创建变分量子电路,将经典数据编码为量子态。 参考 `Quantum embeddings for machine learning `_。 在初始化该类后,其成员函数 ``compute_circuit`` 为运行函数,可作为参数输入 ``QpandaQCircuitVQCLayerLite`` 类构成量子机器学习模型的一层。 :param qubits: 使用pyqpanda 申请的量子比特。 :param machine: 使用pyqpanda 申请的量子虚拟机。 :param num_repetitions_input: 在子模块中对输入进行编码的重复次数。 :param depth_input: 输入数据的特征维度。 :param num_unitary_layers: 每个子模块中变分量子门的重复次数。 :param num_repetitions: 子模块的重复次数。 Example:: from pyvqnet.qnn.pq3 import QpandaQCircuitVQCLayerLite,Quantum_Embedding from pyvqnet.tensor import tensor import pyqpanda3.core as pq depth_input = 2 num_repetitions = 2 num_repetitions_input = 2 num_unitary_layers = 2 loacl_machine = pq.CPUQVM() nq = depth_input * num_repetitions_input qubits = range(nq) cubits = range(nq) data_in = tensor.ones([12, depth_input]) data_in.requires_grad = True qe = Quantum_Embedding(nq, loacl_machine, num_repetitions_input, depth_input, num_unitary_layers, num_repetitions) qlayer = QpandaQCircuitVQCLayerLite(qe.compute_circuit, qe.param_num) data_in.requires_grad = True y = qlayer.forward(data_in) y.backward() print(data_in.grad) 对量子线路进行测量 *********************************** expval ============================ .. py:function:: pyvqnet.qnn.pq3.measure.expval(machine,prog,pauli_str_dict) 提供的哈密顿量观测值的期望值。 如果观测值是 :math:`0.7Z\otimes X\otimes I+0.2I\otimes Z\otimes I`, 那么 Hamiltonian dict 将是 ``{{'Z0, X1':0.7} ,{'Z1':0.2}}`` 。 expval api现在支持pyqpanda3 的模拟器 。 :param machine: 由pyQPanda创建的量子虚拟机。 :param prog: pyQPanda创建的量子工程。 :param pauli_str_dict: 哈密顿量观测值。 :return: 期望值。 Example:: import pyqpanda3.core as pq from pyvqnet.qnn.pq3.measure import expval input = [0.56, 0.1] m_machine = pq.CPUQVM() m_qlist = range(3) cir = pq.QCircuit(3) cir<111 开始。 :param indices: 所考虑子系统中的量子比特索引列表。 :return: 大小为“(2**len(indices), 2**len(indices))”的密度矩阵。 Example:: from pyvqnet.qnn.pq3.measure import DensityMatrixFromQstate qstate = [(0.9306699299765968+0j), (0.18865613455240968+0j), (0.1886561345524097+0j), (0.03824249173404786+0j), -0.048171819846746615j, -0.00976491131165138j, -0.23763904794287155j, -0.048171819846746615j] print(DensityMatrixFromQstate(qstate,[0,1])) # [[0.86846704+0.j 0.1870241 +0.j 0.17604699+0.j 0.03791166+0.j] # [0.1870241 +0.j 0.09206345+0.j 0.03791166+0.j 0.01866219+0.j] # [0.17604699+0.j 0.03791166+0.j 0.03568649+0.j 0.00768507+0.j] # [0.03791166+0.j 0.01866219+0.j 0.00768507+0.j 0.00378301+0.j]] VN_Entropy ============== .. py:function:: pyvqnet.qnn.pq3.measure.VN_Entropy(state, indices, base=None) 根据给定 qubits 列表上的状态向量计算Von Neumann熵 。 .. math:: S( \rho ) = -\text{Tr}( \rho \log ( \rho )) :param state: 一维列表状态向量。 这个列表的大小应该是 ``(2**N,)`` 对于量子比特个数 ``N`` ,qstate 应该从 000 ->111 开始。 :param indices: 所考虑子系统中的量子比特索引列表。 :param base: 对数的底。 如果没有,则使用自然对数。 :return: 冯诺依曼熵的浮点值. Example:: from pyvqnet.qnn.pq3.measure import VN_Entropy qstate = [(0.9022961387408862 + 0j), -0.06676534788028633j, (0.18290448232350312 + 0j), -0.3293638014158896j, (0.03707657410649268 + 0j), -0.06676534788028635j, (0.18290448232350312 + 0j), -0.013534006039561714j] print(VN_Entropy(qstate, [0, 1])) #0.14592917648464448 Mutal_Info ============== .. py:function:: pyvqnet.qnn.pq3.measure.Mutal_Info(state, indices0, indices1, base=None) 根据给定两个子 qubits 列表上的状态向量计算互信息 。 .. math:: I(A, B) = S(\rho^A) + S(\rho^B) - S(\rho^{AB}) 其中 :math:`S` 是冯诺依曼熵。 互信息是衡量两个子系统之间相关性的指标。更具体地说,它量化了一个系统通过测量另一个系统获得的信息量。 每个状态都可以作为计算基础中的状态向量给出。 :param state: 一维列表状态向量。 这个列表的大小应该是 ``(2**N,)`` 对于量子比特个数 ``N`` , qstate 应该从 000 ->111 开始。 :param indices0: 第一个子系统中的量子比特索引列表。 :param indices1: 第二个子系统中的量子比特索引列表。 :param base: 对数的底。 如果为None,则使用自然对数,默认为None。 :return: 子系统之间的相互信息 Example:: from pyvqnet.qnn.pq3.measure import Mutal_Info qstate = [(0.9022961387408862 + 0j), -0.06676534788028633j, (0.18290448232350312 + 0j), -0.3293638014158896j, (0.03707657410649268 + 0j), -0.06676534788028635j, (0.18290448232350312 + 0j), -0.013534006039561714j] print(Mutal_Info(qstate, [0], [2], 2)) #0.13763425302805887 Purity ========================= .. py:function:: pyvqnet.qnn.pq3.measure.Purity(state, qubits_idx) 从态矢中计算特定量子比特上的纯度。 .. math:: \gamma = \text{Tr}(\rho^2) 式中 :math:`\rho` 为密度矩阵。标准化量子态的纯度满足 :math:`\frac{1}{d} \leq \gamma \leq 1` , 其中 :math:`d` 是希尔伯特空间的维数。 纯态的纯度是1。 :param state: 从pyqpanda get_qstate()获取的量子态 :param qubits_idx: 要计算纯度的量子比特位索引 :return: 纯度 Examples:: from pyvqnet.qnn.pq3.measure import Purity qstate = [(0.9306699299765968 + 0j), (0.18865613455240968 + 0j), (0.1886561345524097 + 0j), (0.03824249173404786 + 0j), -0.048171819846746615j, -0.00976491131165138j, -0.23763904794287155j, -0.048171819846746615j] pp = Purity(qstate, [1]) print(pp) #0.902503479761881