使用pyqpanda3量子机器学习模块¶
警告
以下接口的量子计算部分使用pyqpanda3 https://qcloud.originqc.com.cn/document/qpanda-3/index.html。
量子计算层¶
QuantumLayer¶
如您熟悉pyqpanda3语法,可以使用该接口QuantumLayer,自定义pyqpanda3模拟器进行计算。
- 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框架的梯度计算模块,可以使用参数漂移法等计算线路参数的梯度,训练变分量子线路模型或将变分量子线路嵌入混合量子和经典模型。
- 参数:
qprog_with_measure – 用pyQPand构建的量子线路运行和测量函数。
para_num – int - 参数个数。
diff_method – 求解量子线路参数梯度的方法,“参数位移”或“有限差分”,默认参数偏移。
delta – 有限差分计算梯度时的 delta。
dtype – 参数的数据类型,defaults:None,使用默认数据类型:kfloat32,代表32位浮点数。
name – 这个模块的名字, 默认为””。
- 返回:
一个可以计算量子线路的模块。
备注
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: 输入一维的变分量子线路的待训练参数。
备注
该类具有别名 QuantumLayerV2, QpandaQCircuitVQCLayerLite。
备注
该类计算梯度需要额外使用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<<pq.H(qubits[0]) circuit<<pq.H(qubits[1]) circuit<<pq.H(qubits[2]) circuit<<pq.H(qubits[3]) circuit<<pq.RZ(qubits[0],input[0]) circuit<<pq.RZ(qubits[1],input[1]) circuit<<pq.RZ(qubits[2],input[2]) circuit<<pq.RZ(qubits[3],input[3]) circuit<<pq.CNOT(qubits[0],qubits[1]) circuit<<pq.RZ(qubits[1],param[0]) circuit<<pq.CNOT(qubits[0],qubits[1]) circuit<<pq.CNOT(qubits[1],qubits[2]) circuit<<pq.RZ(qubits[2],param[1]) circuit<<pq.CNOT(qubits[1],qubits[2]) circuit<<pq.CNOT(qubits[2],qubits[3]) circuit<<pq.RZ(qubits[3],param[2]) circuit<<pq.CNOT(qubits[2],qubits[3]) prog = pq.QProg() prog<<circuit rlt_prob = ProbsMeasure(m_machine,prog,[0,2]) return rlt_prob pqc = QuantumLayer(pqctest,3) #classic data as input input = QTensor([[1,2,3,4],[4,2,2,3],[3.0,3,2,2]] ) #forward circuits rlt = pqc(input) print(rlt) grad = ones(rlt.data.shape)*1000 #backward circuits rlt.backward(grad) print(pqc.m_para.grad)
QpandaQProgVQCLayer¶
- class pyvqnet.qnn.pq3.quantumlayer.QpandaQProgVQCLayer(origin_qprog_func, para_num, qvm_type='cpu', pauli_str_dict=None, shots=1000, initializer=None, dtype=None, name='')¶
它将参数化的量子电路提交给 本地QPanda3全振幅模拟器中计算,并训练线路中的参数。 它支持批量数据并使用参数移位规则来估计参数的梯度。 对于 CRX、CRY、CRZ,此层使用 https://iopscience.iop.org/article/10.1088/1367-2630/ac2cb3 中的公式,其余逻辑门采用默认的参数漂移法计算梯度。
- 参数:
origin_qprog_func – 由 QPanda 构建的可调用量子电路函数。
para_num – int - 参数数量;参数是一维的。
qvm_type – str - 使用pyqpanda3模拟器类型, cpu 或 gpu 类型,默认 cpu .
pauli_str_dict – dict|list - 表示量子电路中的泡利算子的字典或字典列表。默认值为 None。
shots – int - 测量镜头数。默认值为 1000。
initializer – 参数值的初始化器。默认值为 None。
dtype – 参数的数据类型。默认值为 None,即使用默认数据类型。
name – 模块名称。默认值为空字符串。
- 返回:
返回一个QuantumLayerV3类
备注
origin_qprog_func 是用户使用 pyqpanda3 定义的量子电路函数: https://qcloud.originqc.com.cn/document/qpanda-3/dc/d12/tutorial_quantum_program.html。。
此函数必须包含输入和参数两个参数作为函数入参(即使某个参数未实际使用),输出为pyqpanda3.core.QProg类型数据,否则无法在QuantumLayerV3中正常运行。
origin_qprog_func (input,param )
input:用户定义的数组类输入 1 维经典数据。
param:array_like 输入用户定义的 1 维量子电路参数。
备注
该类具有别名 QuantumLayerV3 。
备注
该类计算梯度需要额外使用pyqpanda3进行线路计算个数与参数个数、数据个数、数据维度的乘积线性相关。
Example:
import pyqpanda3.core as pq import pyvqnet from pyvqnet.qnn.pq3.quantumlayer import QpandaQProgVQCLayer def qfun(input, param ): m_qlist = range(3) cubits = range(3) measure_qubits = [0,1, 2] m_prog = pq.QProg() cir = pq.QCircuit(3) cir<<pq.RZ(m_qlist[0], input[0]) cir<<pq.RX(m_qlist[2], input[2]) qcir = pq.RX(m_qlist[1], param[1]).control(m_qlist[0]) cir<<qcir qcir = pq.RY(m_qlist[0], param[2]).control(m_qlist[1]) cir<<qcir cir<<pq.RY(m_qlist[0], input[1]) qcir = pq.RZ(m_qlist[0], param[3]).control(m_qlist[1]) cir<<qcir m_prog<<cir for idx, ele in enumerate(measure_qubits): m_prog << pq.measure(m_qlist[ele], cubits[idx]) # pylint: disable=expression-not-assigned return m_prog from pyvqnet.utils.initializer import ones l = QpandaQProgVQCLayer(qfun, 4, "cpu", pauli_str_dict=None, shots=1000, initializer=ones, name="") x = pyvqnet.tensor.QTensor( [[2.56, 1.2,-3]], requires_grad=True) y = l(x) y.backward() print(l.m_para.grad.to_numpy()) print(x.grad.to_numpy())
QuantumBatchAsyncQcloudLayer¶
当您安装最新版本pyqpanda3,可以使用本接口定义一个变分线路,并提交到originqc的真实芯片上运行。
- class pyvqnet.qnn.pq3.quantumlayer.QuantumBatchAsyncQcloudLayer(origin_qprog_func, qcloud_token, para_num, pauli_str_dict=None, shots=1000, initializer=None, dtype=None, name='', diff_method='parameter_shift', submit_kwargs={}, query_kwargs={})¶
使用 pyqpanda3 QCloud 的本源量子真实芯片的抽象计算模块。 它提交参数化量子电路到真实芯片并获得测量结果。 如果 diff_method == “random_coordinate_descent” ,该层将随机选择单个参数来计算梯度,其他参数将保持为零。参考:https://arxiv.org/abs/2311.00088
备注
qcloud_token 为您到 https://qcloud.originqc.com.cn/ 中申请的api token。 origin_qprog_func 需要返回pypqanda3.core.QProg类型的数据,如果没有设置pauli_str_dict,需要保证该QProg中已经插入了measure。 origin_qprog_func 的形式必须按照如下:
origin_qprog_func(input,param)
input: 输入1~2维经典数据,二维的情况下,第一个维度为批处理大小。
param: 输入一维的变分量子线路的待训练参数。
备注
该类计算梯度需要额外使用芯片进行线路计算个数与参数个数、数据个数、数据维度的乘积线性相关。
- 参数:
origin_qprog_func – QPanda 构建的变分量子电路函数,必须返回QProg。
qcloud_token – str - 量子机的类型或用于执行的云令牌。
para_num – int - 参数数量,参数是大小为[para_num]的QTensor。
pauli_str_dict – dict|list - 表示量子电路中泡利运算符的字典或字典列表。 默认为“无”,则进行测量操作,如果输入泡利算符的字典,则会计算单个期望或者多个期望。
shot – int - 测量次数。 默认值为 1000。
initializer – 参数值的初始化器。 默认为“无”,使用0~2*pi正态分布。
dtype – 参数的数据类型。 默认值为 None,即使用默认数据类型pyvqnet.kfloat32。
name – 模块的名称。 默认为空字符串。
diff_method – 梯度计算的微分方法。 默认为“parameter_shift”,”random_coordinate_descent”。
submit_kwargs – 用于提交量子电路的附加关键字参数,默认:{“chip_id”:”origin_wukong”,”is_amend”:True,”is_mapping”:True,”is_optimization”:True,”compile_level”:3,”default_task_group_size”:200,”test_qcloud_fake”:False},当设置test_qcloud_fake为True则本地CPUQVM模拟。
query_kwargs – 用于查询量子结果的附加关键字参数,默认:{“timeout”:2,”print_query_info”:True,”sub_circuits_split_size”:1}。
- 返回:
一个可以计算量子电路的模块。
Example:
import pyqpanda3.core as pq import pyvqnet from pyvqnet.qnn.pq3.quantumlayer import QuantumBatchAsyncQcloudLayer def qfun(input,param): measure_qubits = [0,2] m_qlist = range(6) cir = pq.QCircuit(6) cir << (pq.RZ(m_qlist[0],input[0])) cir << pq.CNOT(m_qlist[0],m_qlist[1]) cir << pq.RY(m_qlist[1],param[0]) cir << pq.CNOT(m_qlist[0],m_qlist[2]) cir << pq.RZ(m_qlist[1],input[1]) cir << pq.RY(m_qlist[2],param[1]) cir << pq.H(m_qlist[2]) m_prog = pq.QProg(cir) for idx, ele in enumerate(measure_qubits): m_prog << pq.measure(m_qlist[ele], m_qlist[idx]) # pylint: disable=expression-not-assigned return m_prog l = QuantumBatchAsyncQcloudLayer(qfun, "3047DE8A59764BEDAC9C3282093B16AF1", 2, pauli_str_dict=None, shots = 1000, initializer=None, dtype=None, name="", diff_method="parameter_shift", submit_kwargs={"test_qcloud_fake":True}, query_kwargs={}) x = pyvqnet.tensor.QTensor([[0.56,1.2],[0.56,1.2],[0.56,1.2],[0.56,1.2],[0.56,1.2]],requires_grad= True) y = l(x) print(y) y.backward() print(l.m_para.grad) print(x.grad) def qfun2(input,param ): m_qlist = range(6) cir = pq.QCircuit(6) cir<<pq.RZ(m_qlist[0],input[0]) cir<<pq.CNOT(m_qlist[0],m_qlist[1]) cir<<pq.RY(m_qlist[1],param[0]) cir<<pq.CNOT(m_qlist[0],m_qlist[2]) cir<<pq.RZ(m_qlist[1],input[1]) cir<<pq.RY(m_qlist[2],param[1]) cir<<pq.H(m_qlist[2]) m_prog = pq.QProg(cir) return m_prog l = QuantumBatchAsyncQcloudLayer(qfun2, "3047DE8A59764BEDAC9C3282093B16AF", 2, pauli_str_dict={'Z0 X1':10,'':-0.5,'Y2':-0.543,"":3333}, shots = 1000, initializer=None, dtype=None, name="", diff_method="parameter_shift", submit_kwargs={"test_qcloud_fake":True}, query_kwargs={}) x = pyvqnet.tensor.QTensor([[0.56,1.2],[0.56,1.2],[0.56,1.2],[0.56,1.2]],requires_grad= True) y = l(x) print(y) y.backward() print(l.m_para.grad) print(x.grad)
grad¶
- pyvqnet.qnn.pq3.quantumlayer.grad(quantum_prog_func, input_params, *args)¶
grad 函数提供了一种对用户设计的含参量子线路参数的梯度进行计算的接口。 用户可按照如下例子,使用pyqpanda设计线路运行函数
quantum_prog_func
,并作为参数送入grad函数。 grad函数的第二个参数则是想要计算量子逻辑门参数梯度的坐标。 返回值的形状为 [num of parameters,num of output]。- 参数:
quantum_prog_func – pyqpanda设计的量子线路运行函数。
input_params – 待求梯度的参数。
*args – 其他输入到quantum_prog_func函数的参数。
- 返回:
参数的梯度
Examples:
from pyvqnet.qnn.pq3 import grad, ProbsMeasure import pyqpanda3.core as pq def pqctest(param): machine = pq.CPUQVM() qubits = range(2) circuit = pq.QCircuit(2) circuit<<pq.RX(qubits[0], param[0]) circuit<<pq.RY(qubits[1], param[1]) circuit<<pq.CNOT(qubits[0], qubits[1]) circuit<<pq.RX(qubits[1], param[2]) prog = pq.QProg() prog<<circuit EXP = ProbsMeasure(machine,prog,[1]) return EXP g = grad(pqctest, [0.1,0.2, 0.3]) print(g) exp = pqctest([0.1,0.2, 0.3]) print(exp)
HybirdVQCQpanda3QVMLayer¶
- class pyvqnet.qnn.pq3.hybird_vqc_qpanda.HybirdVQCQpanda3QVMLayer(vqc_module: Module, qcloud_token: str, pauli_str_dict: List[Dict] | Dict | None = None, shots: int = 1000, dtype: int | None = None, name: str = '', submit_kwargs: Dict = {}, query_kwargs: Dict = {})¶
混合 vqc 和 qpanda3 模拟计算。该层将用户 forward 函数定义的VQNet编写的量子线路计算转化为QPanda OriginIR,在QPanda3本地虚拟机或者云端服务上进行前向运行,并在基于自动微分计算线路参数梯度,降低了使用参数漂移法计算的时间复杂度。 其中
vqc_module
为用户自定义的量子变分线路模型,其中的QMachine设置save_ir=True
。 有别名HybirdVQCQpandaQVMLayer
。- 参数:
vqc_module – 带有 forward() 的 vqc_module。
qcloud_token – str - 量子机器的类型或用于执行的云令牌。
pauli_str_dict – dict|list - 表示量子电路中泡利算子的字典或字典列表。默认值为 None。
shots – int - 量子线路测量次数。默认值为 1000。
name – 模块名称。默认值为空字符串。
submit_kwargs – 提交量子电路的附加关键字参数,默认值: {“chip_id”:”origin_wukong”, “is_amend”:True,”is_mapping”:True, “is_optimization”:True, “default_task_group_size”:200, “test_qcloud_fake”:True}。
query_kwargs – 查询量子结果的附加关键字参数,默认值:{“timeout”:2,”print_query_info”:True,”sub_circuits_split_size”:1}。
- 返回:
可以计算量子电路的模块。
备注
pauli_str_dict 不能为 None,并且应与 vqc_module 测量函数中的 obs 相同。 vqc_module 应具有 QMachine 类型的属性,QMachine 应设置 save_ir=True
Example:
from pyvqnet.qnn.vqc import * from pyvqnet.qnn.pq3 import HybirdVQCQpanda3QVMLayer import pyvqnet from pyvqnet.nn import Module,Linear class Hybird(Module): def __init__(self): self.cl1 = Linear(3,3) self.ql = QModel(num_wires=6, dtype=pyvqnet.kcomplex64) self.cl2 = Linear(1,2) def forward(self,x): x = self.cl1(x) x = self.ql(x) x = self.cl2(x) return x class QModel(Module): def __init__(self, num_wires, dtype,grad_mode=""): super(QModel, self).__init__() self._num_wires = num_wires self._dtype = dtype self.qm = QMachine(num_wires, dtype=dtype,grad_mode=grad_mode,save_ir=True) self.rx_layer = RX(has_params=True, trainable=False, wires=0) self.ry_layer = RY(has_params=True, trainable=False, wires=1) self.rz_layer = RZ(has_params=True, trainable=False, wires=1) self.u1 = U1(has_params=True,trainable=True,wires=[2]) self.u2 = U2(has_params=True,trainable=True,wires=[3]) self.u3 = U3(has_params=True,trainable=True,wires=[1]) self.i = I(wires=[3]) self.s = S(wires=[3]) self.x1 = X1(wires=[3]) self.y1 = Y1(wires=[3]) self.z1 = Z1(wires=[3]) self.x = PauliX(wires=[3]) self.y = PauliY(wires=[3]) self.z = PauliZ(wires=[3]) self.swap = SWAP(wires=[2,3]) self.cz = CZ(wires=[2,3]) self.cr = CR(has_params=True,trainable=True,wires=[2,3]) self.rxx = RXX(has_params=True,trainable=True,wires=[2,3]) self.rzz = RYY(has_params=True,trainable=True,wires=[2,3]) self.ryy = RZZ(has_params=True,trainable=True,wires=[2,3]) self.rzx = RZX(has_params=True,trainable=False, wires=[2,3]) self.toffoli = Toffoli(wires=[2,3,4],use_dagger=True) self.h =Hadamard(wires=[1]) self.iSWAP = iSWAP(False,False,wires=[0,2]) self.tlayer = T(wires=1) self.cnot = CNOT(wires=[0, 1]) self.measure = MeasureAll(obs={'Z0':2,'Y3':3} ) def forward(self, x, *args, **kwargs): self.qm.reset_states(x.shape[0]) self.i(q_machine=self.qm) self.s(q_machine=self.qm) self.swap(q_machine=self.qm) self.cz(q_machine=self.qm) self.x(q_machine=self.qm) self.x1(q_machine=self.qm) self.y(q_machine=self.qm) self.y1(q_machine=self.qm) self.z(q_machine=self.qm) self.z1(q_machine=self.qm) self.ryy(q_machine=self.qm) self.rxx(q_machine=self.qm) self.rzz(q_machine=self.qm) self.rzx(q_machine=self.qm,params = x[:,[1]]) self.cr(q_machine=self.qm) self.u1(q_machine=self.qm) self.u2(q_machine=self.qm) self.u3(q_machine=self.qm) self.rx_layer(params = x[:,[0]], q_machine=self.qm) self.cnot(q_machine=self.qm) self.h(q_machine=self.qm) self.iSWAP(q_machine=self.qm) self.ry_layer(params = x[:,[1]], q_machine=self.qm) self.tlayer(q_machine=self.qm) self.rz_layer(params = x[:,[2]], q_machine=self.qm) self.toffoli(q_machine=self.qm) rlt = self.measure(q_machine=self.qm) return rlt input_x = tensor.QTensor([[0.1, 0.2, 0.3]]) input_x = tensor.broadcast_to(input_x,[2,3]) input_x.requires_grad = True qunatum_model = QModel(num_wires=6, dtype=pyvqnet.kcomplex64) l = HybirdVQCQpanda3QVMLayer(qunatum_model, "3047DE8A59764BEDAC9C3282093B16AF1", pauli_str_dict={'Z0':2,'Y3':3}, shots = 1000, name="", submit_kwargs={"test_qcloud_fake":True}, query_kwargs={}) y = l(input_x) print(y) y.backward() print(input_x.grad)
QLinear¶
QLinear 实现了一种量子全连接算法。首先将数据编码到量子态,然后通过量子线路进行演化操作和测量得到最终的全连接结果。

- class pyvqnet.qnn.qlinear.QLinear(input_channels, output_channels, machine: str = "CPU"))¶
量子全连接模块。全连接模块的输入为形状(输入通道、输出通道)。
备注
请注意,该层不带变分量子参数。
- 参数:
input_channels – int - 输入通道数。
output_channels – int - 输出通道数。
machine – str - 使用的虚拟机,默认使用CPU模拟。
- 返回:
量子全连接层。
Exmaple:
from pyvqnet.tensor import QTensor from pyvqnet.qnn.qlinear import QLinear params = [[0.37454012, 0.95071431, 0.73199394, 0.59865848, 0.15601864, 0.15599452], [1.37454012, 0.95071431, 0.73199394, 0.59865848, 0.15601864, 0.15599452], [1.37454012, 1.95071431, 0.73199394, 0.59865848, 0.15601864, 0.15599452], [1.37454012, 1.95071431, 1.73199394, 1.59865848, 0.15601864, 0.15599452]] m = QLinear(6, 2) input = QTensor(params, requires_grad=True) output = m(input) output.backward() print(output) #[ #[0.0568473, 0.1264389], #[0.1524036, 0.1264389], #[0.1524036, 0.1442845], #[0.1524036, 0.1442845] #]
Qconv¶
Qconv是一种量子卷积算法接口。 量子卷积操作采用量子线路对经典数据进行卷积操作,其无需计算乘法和加法操作,只需将数据编码到量子态,然后通过量子线路进行演化操作和测量得到最终的卷积结果。 根据卷积核的范围中的输入数据数量申请相同数量的量子比特,然后构建量子线路进行计算。

其量子线路由每个qubit上首先插入 \(RY\) , \(RZ\) 门进行编码,接着在任意两个qubit上使用 \(Z\) 以及 \(U3\) 进行信息纠缠和交换。下图为4qubits的例子

- class pyvqnet.qnn.qcnn.qconv.QConv(input_channels, output_channels, quantum_number, stride=(1, 1), padding=(0, 0), kernel_initializer=normal, machine: str = 'CPU', dtype=None, name='')¶
量子卷积模块。用量子线路取代Conv2D内核,conv模块的输入为形状(批次大小、输入通道、高度、宽度) Samuel et al. (2020) 。
- 参数:
input_channels – int - 输入通道数。
output_channels – int - 输出通道数。
quantum_number – int - 单个内核的大小。
stride – tuple - 步长,默认为(1,1)。
padding – tuple - 填充,默认为(0,0)。
kernel_initializer – callable - 默认为正态分布。
machine – str - 使用的虚拟机,默认使用CPU模拟。
dtype – 参数的数据类型,defaults:None,使用默认数据类型:kfloat32,代表32位浮点数。
name – 这个模块的名字, 默认为””。
- 返回:
量子卷积层。
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还封装了部分在量子机器学习中常用的量子逻辑门组合:
BasicEmbeddingCircuit¶
- pyvqnet.qnn.pq3.template.BasicEmbeddingCircuit(input_feat, qlist)¶
将n个二进制特征编码为n个量子比特的基态。
例如, 对于
features=([0, 1, 1])
, 在量子系统下其基态为 \(|011 \rangle\)。- 参数:
input_feat –
(n)
大小的二进制输入。qlist – 构建该模板线路量子比特。
- 返回:
量子线路。
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¶
- pyvqnet.qnn.pq3.template.AngleEmbeddingCircuit(input_feat, qubits, rotation: str = 'X')¶
将 \(N\) 特征编码到 \(n\) 量子比特的旋转角度中, 其中 \(N \leq n\)。
旋转可以选择为 : ‘X’ , ‘Y’ , ‘Z’, 如
rotation
的参数定义为:rotation='X'
将特征用作RX旋转的角度。rotation='Y'
将特征用作RY旋转的角度。rotation='Z'
将特征用作RZ旋转的角度。
features
的长度必须小于或等于量子比特的数量。如果features
中的长度少于量子比特,则线路不应用剩余的旋转门。- 参数:
input_feat – 表示参数的numpy数组。
qubits – 量子比特索引。
rotation – 使用什么旋转,默认为“X”。
- 返回:
量子线路。
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¶
- pyvqnet.qnn.pq3.template.IQPEmbeddingCircuits(input_feat, qubits, rep: int = 1)¶
使用IQP线路的对角门将 \(n\) 特征编码为 \(n\) 量子比特。
编码是由 Havlicek et al. (2018) 提出。
通过指定
n_repeats
,可以重复基本IQP线路。- 参数:
input_feat – 表示参数的numpy数组。
qubits – 量子比特索引列表。
rep – 重复量子线路块,默认次数1。
- 返回:
量子线路。
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¶
- pyvqnet.qnn.pq3.template.RotCircuit(para, qubits)¶
任意单量子比特旋转。qlist的数量应该是1,参数的数量应该是3。
\[\begin{split}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}.\end{split}\]- 参数:
para – 表示参数 \([\phi, \theta, \omega]\) 的numpy数组。
qubits – 量子比特索引,只接受单个量子比特。
- 返回:
量子线路。
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¶
- pyvqnet.qnn.pq3.template.CRotCircuit(para, control_qubits, rot_qubits)¶
受控Rot操作符。
\[\begin{split}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}.\end{split}\]- 参数:
para – 表示参数 \([\phi, \theta, \omega]\) 的numpy数组。
control_qubits – 量子比特索引,量子比特的数量应为1。
rot_qubits – Rot量子比特索引,量子比特的数量应为1。
- 返回:
量子线路。
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¶
- pyvqnet.qnn.pq3.template.CSWAPcircuit(qubits)¶
受控SWAP线路。
\[\begin{split}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}.\end{split}\]备注
提供的第一个量子比特对应于 control qubit 。
- 参数:
qubits – 量子比特索引列表第一个量子比特是控制量子比特。qlist的长度必须为3。
- 返回:
量子线路。
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¶
- pyvqnet.qnn.pq3.template.Controlled_Hadamard(qubits)¶
受控Hadamard逻辑门
\[\begin{split}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}.\end{split}\]- 参数:
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¶
- pyvqnet.qnn.pq3.template.CCZ(qubits)¶
受控-受控-Z (controlled-controlled-Z) 逻辑门。
\[\begin{split}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}\end{split}\]- 参数:
qubits – 量子比特索引。
- 返回:
pyqpanda QCircuit
Example:
import pyqpanda3.core as pq machine = pq.CPUQVM() qubits = range(3) from pyvqnet.qnn.pq3 import CCZ cir = CCZ(qubits)
FermionicSingleExcitation¶
- pyvqnet.qnn.pq3.template.FermionicSingleExcitation(weight, wires, qubits)¶
对泡利矩阵的张量积求幂的耦合簇单激励算子。矩阵形式下式给出:
\[\hat{U}_{pr}(\theta) = \mathrm{exp} \{ \theta_{pr} (\hat{c}_p^\dagger \hat{c}_r -\mathrm{H.c.}) \},\]- 参数:
weight – 量子比特 p 上的变参.
wires – 表示区间[r, p]中的量子比特索引子集。最小长度必须为2。第一索引值被解释为r,最后一个索引值被解释为p。 中间的索引被CNOT门作用,以计算量子位集的奇偶校验。
qubits – 量子比特索引。
- 返回:
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¶
- pyvqnet.qnn.pq3.template.FermionicDoubleExcitation(weight, wires1, wires2, qubits)¶
对泡利矩阵的张量积求幂的耦合聚类双激励算子,矩阵形式由下式给出:
\[\hat{U}_{pqrs}(\theta) = \mathrm{exp} \{ \theta (\hat{c}_p^\dagger \hat{c}_q^\dagger \hat{c}_r \hat{c}_s - \mathrm{H.c.}) \},\]其中 \(\hat{c}\) 和 \(\hat{c}^\dagger\) 是费米子湮灭和 创建运算符和索引 \(r, s\) 和 \(p, q\) 在占用的和 分别为空分子轨道。 使用 Jordan-Wigner 变换 上面定义的费米子算子可以写成 根据 Pauli 矩阵(有关更多详细信息,请参见 arXiv:1805.04340)
\[\begin{split}\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\}\end{split}\]- 参数:
weight – 可变参数
wires1 – 代表的量子比特的索引列表区间 [s, r] 中占据量子比特的子集。第一个索引被解释为 s,最后一索引被解释为 r。 CNOT 门对中间的索引进行操作,以计算一组量子位的奇偶性。
wires2 – 代表的量子比特的索引列表区间 [q, p] 中占据量子比特的子集。第一根索引被解释为 q,最后一索引被解释为 p。 CNOT 门对中间的索引进行操作,以计算一组量子位的奇偶性。
qubits – 量子比特索引。
- 返回:
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¶
- pyvqnet.qnn.pq3.template.UCCSD(weights, wires, s_wires, d_wires, init_state, qubits)¶
实现酉耦合簇单激发和双激发拟设(UCCSD)。UCCSD 是 VQE 拟设,通常用于运行量子化学模拟。
在一阶 Trotter 近似内,UCCSD 酉函数由下式给出:
\[\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\}\]其中 \(\hat{c}\) 和 \(\hat{c}^\dagger\) 是费米子湮灭和 创建运算符和索引 \(r, s\) 和 \(p, q\) 在占用的和 分别为空分子轨道。(更多细节见 arXiv:1805.04340):
- 参数:
weights – 包含参数的大小
(len(s_wires)+ len(d_wires))
张量 \(\theta_{pr}\) 和 \(\theta_{pqrs}\) 输入 Z 旋转FermionicSingleExcitation
和FermionicDoubleExcitation
。wires – 模板作用的量子比特索引
s_wires – 包含量子比特索引的列表序列
[r,...,p]
由单一激发产生 \(\vert r, p \rangle = \hat{c}_p^\dagger \hat{c}_r \vert \mathrm{HF} \rangle\), 其中 \(\vert \mathrm{HF} \rangle\) 表示 Hartee-Fock 参考态。d_wires – 列表序列,每个列表包含两个列表 指定索引
[s, ...,r]
和[q,..., p]
定义双激励 \(\vert s, r, q, p \rangle = \hat{c}_p^\dagger \hat{c}_q^\dagger \hat{c}_r\hat{c}_s \vert \mathrm{HF} \rangle\) 。init_state – 长度
len(wires)
occupation-number vector 表示 高频状态。init_state
在量子比特初始化状态。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¶
- pyvqnet.qnn.pq3.template.QuantumPoolingCircuit(sources_wires, sinks_wires, params, qubits)¶
对数据进行降采样的量子电路。
为了减少电路中的量子位数量,首先在系统中创建成对的量子位。在最初配对所有量子位之后,将广义2量子位酉元应用于每一对量子位上。并在应用这两个量子位酉元之后,在神经网络的其余部分忽略每对量子位中的一个量子位。
- 参数:
sources_wires – 将被忽略的源量子位索引。
sinks_wires – 将保留的目标量子位索引。
params – 输入参数。
qubits – 量子比特索引。
- 返回:
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¶
- 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 的量子线路。- 参数:
qubits – 量子比特索引。
single_rot_gate_list – 单个量子位旋转门列表由一个或多个作用于每个量子位的旋转门构成。目前支持 Rx、Ry、Rz。
entangle_gate – 非参数化纠缠门。支持CNOT、CZ。默认: CNOT。
entangle_rules – 电路中如何使用纠缠门。
linear
意味着纠缠门将作用于每个相邻的量子位。all
意味着纠缠门将作用于任何两个 qbuits。 默认值:linear
。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¶
- class pyvqnet.qnn.pq3.template.BasicEntanglerTemplate(weights=None, num_qubits=1, rotation=pyqpanda.RX)¶
由每个量子位上的单参数单量子位旋转组成的层,后跟一个闭合链或环组合的多个CNOT 门。
CNOT 门环将每个量子位与其邻居连接起来,最后一个量子位被认为是第一个量子位的邻居。
层数 \(L\) 由参数
weights
的第一个维度决定。通过其成员函数
create_circuit
返回 pyqpanda3 的量子线路。- 参数:
weights – 形状的权重张量 (L, len(qubits))。 每个权重都用作量子含参门中的参数。默认值为:
None
,则使用 (1,1) 正态分布随机数作为权重。num_qubits – 量子比特数,默认为1。
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¶
- class pyvqnet.qnn.pq3.template.StronglyEntanglingTemplate(weights=None, num_qubits=1, ranges=None)¶
由单个量子比特旋转和纠缠器组成的层,参考 circuit-centric classifier design .
参数
weights
包含每一层的权重。 因此得出层数 \(L\) 等于weights
的第一个维度。其包含2-qubit CNOT 门,作用于 \(M\) 个量子比特上,:math:i = 1,…,M。 每个门的第二个量子位标号由公式 \((i+r)\mod M\) 给出,其中 \(r\) 是一个称为
range
的超参数,并且 \(0 < r < M\)。通过其成员函数
create_circuit
返回 pyqpanda3 的量子线路。- 参数:
weights – 形状为
(L, M, 3)
的权重张量,默认值:None,使用形状为(1,1,3)
的随机张量。num_qubits – 量子比特数,默认值:1。
ranges – 确定每个后续层的范围超参数的序列; 默认值:None,使用 \(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¶
- class pyvqnet.qnn.pq3.ComplexEntangelingTemplate(weights, num_qubits, depth)¶
由 U3 门和 CNOT 门组成的强纠缠层。 此线路模板来自以下论文:https://arxiv.org/abs/1804.00633。
通过其成员函数
create_circuit
返回 pyqpanda3 的量子线路。- 参数:
weights – 参数,[depth,num_qubits,3]的形状
num_qubits – 量子比特数。
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¶
- 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
类构成量子机器学习模型的一层。- 参数:
qubits – 使用pyqpanda 申请的量子比特。
machine – 使用pyqpanda 申请的量子虚拟机。
num_repetitions_input – 在子模块中对输入进行编码的重复次数。
depth_input – 输入数据的特征维度。
num_unitary_layers – 每个子模块中变分量子门的重复次数。
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¶
- pyvqnet.qnn.pq3.measure.expval(machine, prog, pauli_str_dict)¶
提供的哈密顿量观测值的期望值。
如果观测值是 \(0.7Z\otimes X\otimes I+0.2I\otimes Z\otimes I\), 那么 Hamiltonian dict 将是
{{'Z0, X1':0.7} ,{'Z1':0.2}}
。expval api现在支持pyqpanda3 的模拟器 。
- 参数:
machine – 由pyQPanda创建的量子虚拟机。
prog – pyQPanda创建的量子工程。
pauli_str_dict – 哈密顿量观测值。
- 返回:
期望值。
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<<pq.RZ(m_qlist[0],input[0]) cir<<pq.CNOT(m_qlist[0],m_qlist[1]) cir<<pq.RY(m_qlist[1],input[1]) cir<<pq.CNOT(m_qlist[0],m_qlist[2]) m_prog = pq.QProg(cir) pauli_dict = {'Z0 X1':10,'Y2':-0.543} exp2 = expval(m_machine,m_prog,pauli_dict) print(exp2)
QuantumMeasure¶
- pyvqnet.qnn.pq3.measure.QuantumMeasure(machine, prog, measure_qubits: list, shots: int = 1000, qcloud_option='')¶
计算量子线路测量。返回通过蒙特卡罗方法获得的测量结果。
更多详情请访问 https://pyqpanda-toturial.readthedocs.io/zh/latest/Measure.html?highlight=measure_all 。
QuantumMeasure api现在只支持QPanda
CPUQVM
或QCloud
。- 参数:
machine – pyQPanda分配的量子虚拟机。
prog – pyQPanda创建的量子工程。
measure_qubits – 列表包含测量比特索引。
shots – 测量次数,默认值为1000次。
qcloud_option – 设置 qcloud 配置,默认为“”,可以传入一个QCloudOptions类,只在使用qcloud 下有用。
- 返回:
返回通过蒙特卡罗方法获得的测量结果。
Example:
from pyqpanda3.core import * circuit = QCircuit(3) circuit << H(0) circuit << P(2, 0.2) circuit << RX(1, 0.9) circuit << RX(0, 0.6) circuit << RX(1, 0.3) circuit << RY(1, 0.3) circuit << RY(2, 2.7) circuit << RX(0, 1.5) prog = QProg() prog.append(circuit) machine = CPUQVM() from pyvqnet.qnn.pq3.measure import probs_measure,quantum_measure measure_result = quantum_measure(machine,prog,[2,0]) print(measure_result)
ProbsMeasure¶
- pyvqnet.qnn.pq3.measure.ProbsMeasure(machine, prog, measure_qubits: list, shots=1)¶
计算线路概率测量。
更多详情请访问 https://pyqpanda-toturial.readthedocs.io/zh/latest/PMeasure.html。
ProbsMeasure api现在只支持pyQPanda
CPUQVM
或QCloud
。- 参数:
measure_qubits – 列表包含测量比特索引
prog – qpanda创建的量子工程。
machine – pyQPanda分配的量子虚拟机。
shots – 测量次数,默认为1,计算理论值。
- 返回:
按字典顺序测量量子比特。
Example:
from pyqpanda3.core import * from pyvqnet.qnn.pq3.measure import probs_measure circuit = QCircuit(3) circuit << H(0) circuit << P(2, 0.2) circuit << RX(1, 0.9) circuit << RX(0, 0.6) circuit << RX(1, 0.3) circuit << RY(1, 0.3) circuit << RY(2, 2.7) circuit << RX(0, 1.5) prog = QProg() prog.append(circuit) prog.append(measure(0, 0)) prog.append(measure(1, 1)) prog.append(measure(2, 2)) machine = CPUQVM() measure_result = probs_measure(machine,prog,[2,0]) print(measure_result) #[0.04796392899146941, 0, 0.4760180355042653, 0.4760180355042653]
DensityMatrixFromQstate¶
- pyvqnet.qnn.pq3.measure.DensityMatrixFromQstate(state, indices)¶
计算量子态在一组特定量子比特上的密度矩阵。
- 参数:
state – 一维列表状态向量。 这个列表的大小应该是
(2**N,)
对于量子比特个数N
,qstate 应该从 000 ->111 开始。indices – 所考虑子系统中的量子比特索引列表。
- 返回:
大小为“(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¶
- pyvqnet.qnn.pq3.measure.VN_Entropy(state, indices, base=None)¶
根据给定 qubits 列表上的状态向量计算Von Neumann熵 。
\[S( \rho ) = -\text{Tr}( \rho \log ( \rho ))\]- 参数:
state – 一维列表状态向量。 这个列表的大小应该是
(2**N,)
对于量子比特个数N
,qstate 应该从 000 ->111 开始。indices – 所考虑子系统中的量子比特索引列表。
base – 对数的底。 如果没有,则使用自然对数。
- 返回:
冯诺依曼熵的浮点值.
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¶
- pyvqnet.qnn.pq3.measure.Mutal_Info(state, indices0, indices1, base=None)¶
根据给定两个子 qubits 列表上的状态向量计算互信息 。
\[I(A, B) = S(\rho^A) + S(\rho^B) - S(\rho^{AB})\]其中 \(S\) 是冯诺依曼熵。
互信息是衡量两个子系统之间相关性的指标。更具体地说,它量化了一个系统通过测量另一个系统获得的信息量。
每个状态都可以作为计算基础中的状态向量给出。
- 参数:
state – 一维列表状态向量。 这个列表的大小应该是
(2**N,)
对于量子比特个数N
, qstate 应该从 000 ->111 开始。indices0 – 第一个子系统中的量子比特索引列表。
indices1 – 第二个子系统中的量子比特索引列表。
base – 对数的底。 如果为None,则使用自然对数,默认为None。
- 返回:
子系统之间的相互信息
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¶
- pyvqnet.qnn.pq3.measure.Purity(state, qubits_idx)¶
从态矢中计算特定量子比特上的纯度。
\[\gamma = \text{Tr}(\rho^2)\]式中 \(\rho\) 为密度矩阵。标准化量子态的纯度满足 \(\frac{1}{d} \leq \gamma \leq 1\) , 其中 \(d\) 是希尔伯特空间的维数。 纯态的纯度是1。
- 参数:
state – 从pyqpanda get_qstate()获取的量子态
qubits_idx – 要计算纯度的量子比特位索引
- 返回:
纯度
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