mindquantum.algorithm.nisq

NISQ算法。

class mindquantum.algorithm.nisq.Ansatz(name, n_qubits, *args, **kwargs)[源代码]

Ansatz的基类。

参数:
  • name (str) - ansatz的名字。

  • n_qubits (int) - ansatz作用于多少个量子比特。

property circuit

获取ansatz的量子线路。

返回:

Circuit,ansatz的量子线路。

class mindquantum.algorithm.nisq.HardwareEfficientAnsatz(n_qubits, single_rot_gate_seq, entangle_gate=X, entangle_mapping='linear', depth=1)[源代码]

HardwareEfficientAnsatz是一种可以很容易地在量子芯片上高效实现的ansatz。

HardwareEfficientAnsatz由一层单比特旋转门和一层双比特纠缠门构成。单比特旋转门层由一个或多个作用于每个量子比特的旋转门构造。 两个量子比特纠缠门层是由CNOT、CZ、XX、YY、ZZ等作用于纠缠映射构建的。了解更多详细信息,请访问 Hardware-efficient variational quantum eigensolver for small molecules and quantum magnets

参数:
  • n_qubits (int) - 此ansatz的比特数。

  • single_rot_gate_seq (list[BasicGate]) - 作用于每个量子比特的参数化旋转门列表。

  • entangle_gate (BasicGate) - 非参数化纠缠门。如果它是单个量子比特门,则将使用控制版本。默认值:XGate。

  • entangle_mapping (Union[str, list[tuple[int]]]) - 纠缠门的纠缠映射。”linear”表示纠缠门将作用于每个相邻的量子比特。”all”表示纠缠门将作用于任何两个两个量子比特。。此外,可以通过将纠缠映射设置为两个量子比特元组的列表来指定要执行纠缠的两个量子比特。默认值:”linear”。

  • depth (int) - ansatz的深度。默认值:1。

样例:

>>> from mindquantum.algorithm.nisq import HardwareEfficientAnsatz
>>> from mindquantum.core.gates import RY, RZ, Z
>>> hea = HardwareEfficientAnsatz(3, [RY, RZ], Z, [(0, 1), (0, 2)])
>>> hea.circuit
q0: ──RY(d0_n0_0)────RZ(d0_n0_1)────●────●────RY(d1_n0_0)────RZ(d1_n0_1)──
                                    │    │
q1: ──RY(d0_n1_0)────RZ(d0_n1_1)────Z────┼────RY(d1_n1_0)────RZ(d1_n1_1)──

q2: ──RY(d0_n2_0)────RZ(d0_n2_1)─────────Z────RY(d1_n2_0)────RZ(d1_n2_1)──
class mindquantum.algorithm.nisq.IQPEncoding(n_feature, first_rotation_gate=RZ, second_rotation_gate=RZ, num_repeats=1)[源代码]

通用IQP编码。

更多信息请参考 Supervised learning with quantum-enhanced feature spaces.

参数:
  • n_feature (int) - IQP编码所需编码的数据的特征数。

  • first_rotation_gate (ParameterGate) - 旋转门RX、RY或RZ之一。

  • second_rotation_gate (ParameterGate) - 旋转门RX、RY或RZ之一。

  • num_repeats (int) - 编码迭代次数。

样例:

>>> import numpy as np
>>> from mindquantum.algorithm.nisq import IQPEncoding
>>> iqp = IQPEncoding(3)
>>> iqp.circuit
q0: ──H────RZ(alpha0)────●───────────────────────────●───────────────────────────────────
                         │                           │
q1: ──H────RZ(alpha1)────X────RZ(alpha0 * alpha1)────X────●───────────────────────────●──
                                                          │                           │
q2: ──H────RZ(alpha2)─────────────────────────────────────X────RZ(alpha1 * alpha2)────X──
>>> iqp.circuit.params_name
['alpha0', 'alpha1', 'alpha2', 'alpha0 * alpha1', 'alpha1 * alpha2']
>>> iqp.circuit.params_name
>>> a = np.array([0, 1, 2])
>>> iqp.data_preparation(a)
array([0, 1, 2, 0, 2])
>>> iqp.circuit.get_qs(pr=iqp.data_preparation(a))
array([-0.28324704-0.21159186j, -0.28324704-0.21159186j,
        0.31027229+0.16950252j,  0.31027229+0.16950252j,
        0.02500938+0.35266773j,  0.02500938+0.35266773j,
        0.31027229+0.16950252j,  0.31027229+0.16950252j])
data_preparation(data)[源代码]

IQP编码的ansatz能够将经典数据编码为量子态。 这种方法将经典数据准备成适合IQP编码的维数。 假设源数据具有 n 特征,那么输出数据将具有 2n1 特征,前 n 个特征是原始数据。对于 m>n

datam=datamndatamn1
参数:
  • data ([list, numpy.ndarray]) - IQP编码了解更多详细信息所需要的经典数据。

返回:

numpy.ndarray,适合此ansatz维度的数据。

class mindquantum.algorithm.nisq.Max2SATAnsatz(clauses, depth=1)[源代码]

Max-2-SAT ansatz。了解更多详细信息,请参考 Reachability Deficits in Quantum Approximate Optimization

U(β,γ)=eβpHbeγpHceβ0Hbeγ0HcHn
Hb=inXi,Hc=lmP(l)

n 是布尔变量的数量, m 是总子句的数量, P(l) 是第一级投影。

参数:
  • clauses (list[tuple[int]]) - Max-2-SAT结构。列表的每个元素都是一个由长度为2的元组表示的子句。元组的元素必须是非零整数。例如,(2,-3)代表子句: x2¬x3

  • depth (int) - Max-2-SAT的深度。默认值:1。

样例:

>>> import numpy as np
>>> from mindquantum.algorithm.nisq import Max2SATAnsatz
>>> clauses = [(2, -3)]
>>> max2sat = Max2SATAnsatz(clauses, 1)
>>> max2sat.circuit
q1: ──H─────RZ(beta_0)────●───────────────────────●────RX(alpha_0)──
                          │                       │
q2: ──H────RZ(-beta_0)────X────RZ(-1/2*beta_0)────X────RX(alpha_0)──
>>> max2sat.hamiltonian
1/4 [] +
1/4 [Z1] +
-1/4 [Z1 Z2] +
-1/4 [Z2]
>>> sats = max2sat.get_sat(4, np.array([4, 1]))
>>> sats
['001', '000', '011', '010']
>>> for i in sats:
...     print(f'sat value: {max2sat.get_sat_value(i)}')
sat value: 1
sat value: 0
sat value: 2
sat value: 1
get_sat(max_n, weight)[源代码]

获取Max-2-SAT问题的字符串。

参数:
  • max_n (int) - 需要的字符串数量。

  • weight (Union[ParameterResolver, dict, numpy.ndarray, list, numbers.Number]) - Max-2-SAT Ansatz的参数值。

返回:

list,字符串列表。

get_sat_value(string)[源代码]

获取给定字符串的 sat 值。 字符串是满足给定Max-2-SAT问题的所有子句的str。

参数:
  • string (str) - Max-2-SAT问题的字符串。

返回:

int,给定字符串下的sat值。

property hamiltonian

获取Max-2-SAT问题的哈密顿量。

返回:

QubitOperator,Max-2-SAT问题的哈密顿量。

class mindquantum.algorithm.nisq.MaxCutAnsatz(graph, depth=1)[源代码]

MaxCut ansatz。了解更多详细信息,请访问 A Quantum Approximate Optimization Algorithm

U(β,γ)=eβpHbeγpHceβ0Hbeγ0HcHn
Hb=inXi,Hc=(i,j)CZiZj

这里: n 是节点的集合, C 是图的边的集合。

参数:
  • graph (list[tuple[int]]) - 图结构。图的每个元素都是由两个节点构造的边。例如,[(0, 1), (1,2)]表示一个三节点的图,且其中一条边连接节点0和节点1,另一条边连接节点1和节点2。

  • depth (int) - MaxCut ansatz的深度。默认值:1。

样例:

>>> from mindquantum.algorithm.nisq import MaxCutAnsatz
>>> graph = [(0, 1), (1, 2), (0, 2)]
>>> maxcut = MaxCutAnsatz(graph, 1)
>>> maxcut.circuit
q0: ──H────ZZ(beta_0)──────────────────ZZ(beta_0)────RX(alpha_0)──
               │                           │
q1: ──H────ZZ(beta_0)────ZZ(beta_0)────────┼─────────RX(alpha_0)──
                             │             │
q2: ──H──────────────────ZZ(beta_0)────ZZ(beta_0)────RX(alpha_0)──
>>>
>>> maxcut.hamiltonian
3/2 [] +
-1/2 [Z0 Z1] +
-1/2 [Z0 Z2] +
-1/2 [Z1 Z2]
>>> maxcut.hamiltonian
>>> partitions = maxcut.get_partition(5, np.array([4, 1]))
>>> for i in partitions:
...     print(f'partition: left: {i[0]}, right: {i[1]}, cut value: {maxcut.get_cut_value(i)}')
partition: left: [2], right: [0, 1], cut value: 2
partition: left: [0, 1], right: [2], cut value: 2
partition: left: [0], right: [1, 2], cut value: 2
partition: left: [0, 1, 2], right: [], cut value: 0
partition: left: [], right: [0, 1, 2], cut value: 0
get_cut_value(partition)[源代码]

获取切割方案的切割边数。切割方案是一个list数组,该list数组由两个list数组构成,每一个list数组包含切割的节点。

参数:
  • partition (list) - 图形切割方案。

返回:

int,给定切割方案下的切割值。

get_partition(max_n, weight)[源代码]

获取MaxCut问题的切割方案。

参数:
  • max_n (int) - 需要多少个切割方案。

  • weight (Union[ParameterResolver, dict, numpy.ndarray, list, numbers.Number]) - MaxCut ansatz的参数值。

返回:

list,切割方案构成的列表。

property hamiltonian

获取MaxCut问题的哈密顿量。

返回:

QubitOperator,MaxCut问题的哈密顿量。

class mindquantum.algorithm.nisq.QubitUCCAnsatz(n_qubits=None, n_electrons=None, occ_orb=None, vir_orb=None, generalized=False, trotter_step=1)[源代码]

量子比特幺正耦合簇(qUCC)是幺正耦合簇的变体,它使用量子比特激励算子而不是费米子激励算子。 量子比特激励算子跨越的Fock空间相当于费米子算子,因此可以使用量子比特激发算子以更高阶的 Trotterization 为代价来近似精确的波函数。

qUCC最大的优点是:即使使用3阶或4阶Trotterization,CNOT门的数量比UCC的原始版本小得多。 此外,尽管变分参数的数量增加,但精度也大大提高。

说明

不包括哈特里-福克电路。 目前,不允许generalized=True,因为需要理论验证。 参考文献: Efficient quantum circuits for quantum computational chemistry

参数:
  • n_qubits (int) - 模拟中量子比特(自旋轨道)的数量。默认值:None。

  • n_electrons (int) - 给定分子的电子数。默认值:None。

  • occ_orb (list) - 手动分配的占用空间轨道的索引。默认值:None。

  • vir_orb (list) - 手动分配的虚拟空间轨道的索引。默认值:None。

  • generalized (bool) - 是否使用不区分占用轨道或虚拟轨道的广义激励(qUCCGSD)。目前,不允许 generalized=True ,因为需要理论验证。默认值:False。

  • trotter_step (int) - 梯度的数量。默认值为1。建议设置大于等于2的值,以获得较好的精度。默认值:1。

样例:

>>> from mindquantum.algorithm.nisq import QubitUCCAnsatz
>>> QubitUCCAnsatz().n_qubits
0
>>> qucc = QubitUCCAnsatz(4, 2, trotter_step=2)
>>> qucc.circuit[:10]
q0: ──X──────────●──────────X───────────────────────────────X──────────●──────────X───────
      │          │          │                               │          │          │
q1: ──┼──────────┼──────────┼────X──────────●──────────X────┼──────────┼──────────┼────X──
      │          │          │    │          │          │    │          │          │    │
q2: ──●────RY(t_0_q_s_0)────●────●────RY(t_0_q_s_1)────●────┼──────────┼──────────┼────┼──
                                                            │          │          │    │
q3: ────────────────────────────────────────────────────────●────RY(t_0_q_s_2)────●────●──
>>> qucc.n_qubits
4
>>> qucc_2 = QubitUCCAnsatz(occ_orb=[0, 1], vir_orb=[2])
>>> qucc_2.operator_pool
[-1.0*t_0_q_s_0 [Q0^ Q4] +
1.0*t_0_q_s_0 [Q4^ Q0] , -1.0*t_0_q_s_1 [Q1^ Q4] +
1.0*t_0_q_s_1 [Q4^ Q1] , -1.0*t_0_q_s_2 [Q2^ Q4] +
1.0*t_0_q_s_2 [Q4^ Q2] , -1.0*t_0_q_s_3 [Q3^ Q4] +
1.0*t_0_q_s_3 [Q4^ Q3] , -1.0*t_0_q_s_4 [Q0^ Q5] +
1.0*t_0_q_s_4 [Q5^ Q0] , -1.0*t_0_q_s_5 [Q1^ Q5] +
1.0*t_0_q_s_5 [Q5^ Q1] , -1.0*t_0_q_s_6 [Q2^ Q5] +
1.0*t_0_q_s_6 [Q5^ Q2] , -1.0*t_0_q_s_7 [Q3^ Q5] +
1.0*t_0_q_s_7 [Q5^ Q3] , -1.0*t_0_q_d_0 [Q1^ Q0^ Q5 Q4] +
1.0*t_0_q_d_0 [Q5^ Q4^ Q1 Q0] , -1.0*t_0_q_d_1 [Q2^ Q0^ Q5 Q4] +
1.0*t_0_q_d_1 [Q5^ Q4^ Q2 Q0] , -1.0*t_0_q_d_2 [Q2^ Q1^ Q5 Q4] +
1.0*t_0_q_d_2 [Q5^ Q4^ Q2 Q1] , -1.0*t_0_q_d_3 [Q3^ Q0^ Q5 Q4] +
1.0*t_0_q_d_3 [Q5^ Q4^ Q3 Q0] , -1.0*t_0_q_d_4 [Q3^ Q1^ Q5 Q4] +
1.0*t_0_q_d_4 [Q5^ Q4^ Q3 Q1] , -1.0*t_0_q_d_5 [Q3^ Q2^ Q5 Q4] +
1.0*t_0_q_d_5 [Q5^ Q4^ Q3 Q2] ]
class mindquantum.algorithm.nisq.StronglyEntangling(n_qubits: int, depth: int, entangle_gate: BasicGate)[源代码]

强纠缠ansatz。请参考 Circuit-centric quantum classifiers

参数:
  • n_qubits (int) - ansatz作用于多少个量子比特。

  • depth (int) - ansatz的深度。

  • entangle_gate (BasicGate) - 产生纠缠的量子门。 如果传入单量子比特门,则会添加一个控制量子比特, 如果传入双量子比特门,则该双量子比特门将作用于不同的量子比特。

样例:

>>> from mindquantum.core.gates import X
>>> from mindquantum.algorithm.nisq import StronglyEntangling
>>> ansatz = StronglyEntangling(3, 2, X)
>>> ansatz.circuit
class mindquantum.algorithm.nisq.Transform(operator, n_qubits=None)[源代码]

将费米子或者玻色子进行转化的模块。 jordan_wigner , parity , bravyi_kitaev , bravyi_kitaev_tree , bravyi_kitaev_superfast 将会把 FermionOperator 转换为 QubitOperatorreversed_jordan_wigner 将会把 QubitOperator 转换为 FermionOperator

参数:
  • operator (Union[FermionOperator, QubitOperator]) - 需要进行转换的 FermionOperatorQubitOperator

  • n_qubits (int) - 输入算符的比特数。如果为 None , 系统将会自动数出比特数。默认值:None。

样例:

>>> from mindquantum.core.operators import FermionOperator
>>> op1 = FermionOperator('1^')
>>> op1
1.0 [1^]
>>> op_transform = Transform(op1)
>>> from mindquantum.algorithm.nisq import Transform
>>> op_transform.jordan_wigner()
0.5 [Z0 X1] +
-0.5j [Z0 Y1]
>>> op_transform.parity()
0.5 [Z0 X1] +
-0.5j [Y1]
>>> op_transform.bravyi_kitaev()
0.5 [Z0 X1] +
-0.5j [Y1]
>>> op_transform.ternary_tree()
0.5 [X0 Z1] +
-0.5j [Y0 X2]
>>> op2 = FermionOperator('1^', 'a')
>>> Transform(op2).jordan_wigner()
0.5*a [Z0 X1] +
-0.5*I*a [Z0 Y1]
bravyi_kitaev()[源代码]

进行Bravyi-Kitaev变换。

Bravyi-Kitaev是介于Jordan-Wigner变换和parity变换之间的变换。也就是说,它平衡了占据的局部性和宇称信息,以提高模拟效率。在此方案中,量子比特存储一组 2x 轨道的宇称,其中 x0 。索引 j 的量子比特总是存储轨道 j 。对于偶数的 j ,这是它存储的唯一轨道。但对于奇数的 j ,它还存储索引小于 j 的一组相邻轨道。 对于占据态变换,我们遵循公式:

bi=[βn]i,jfj,

其中 βnN×N 维平方矩阵, N 是总量子数。量子比特的索引分为三个集合,宇称集、更新集和翻转集。这组量子比特的宇称与索引小于 j 的轨道集具有相同的宇称,因此我们将称这组量子比特索引为“宇称集” j ,或 P(j)

索引为 j 的更新集,或 U(j) 包含除序号为 j 的量子比特会被更新,当轨道 j 被占据时。 索引为 j 的翻转集,或 F(j) ,包含所有的BravyiKitaev量子比特,这些比特将决定量子比特 j 相对于轨道 j 来说是否有相同或者相反的宇称。

请参见论文中的一些详细解释 The Bravyi-Kitaev transformation for quantum computation of electronic structure

本方法基于 Fermionic quantum computationA New Data Structure for Cumulative Frequency Tables 实现。

返回:

QubitOperator,经过 bravyi_kitaev 变换的玻色子算符。

bravyi_kitaev_superfast()[源代码]

作用快速Bravyi-Kitaev变换。 基于 Bravyi-Kitaev Superfast simulation of fermions on a quantum computer 实现。

请注意,只有如下的厄米共轭算符才能进行转换。

C+p,qhp,qapaq+p,q,r,shp,q,r,sapaqaras

其中 C 是一个常数。

返回:

QubitOperator,经过快速bravyi_kitaev变换之后的玻色子算符。

jordan_wigner()[源代码]

应用Jordan-Wigner变换。Jordan-Wigner变换能够保留初始占据数的局域性,并按照如下的形式将费米子转化为玻色子。

ajσjXi=0j1σiZajσj+Xi=0j1σiZ,

其中 σ+=σX+iσYσ=σXiσY 分别是自旋升算符和降算符。

返回:

QubitOperator,Jordan-Wigner变换后的量子比特算符。

parity()[源代码]

应用宇称变换。宇称变换保存初始占据数的非局域性。公式为:

|fM1,fM2,,f0|qM1,qM2,,q0,

其中

qm=|(i=0m1fi)mod 2

该公式可以写成这样,

pi=[πn]i,jfj,

其中 πnN×N 维的方矩阵, N 是总量子比特数。运算按照如下等式进行:

aj12(i=j+1N(σiXX))(σjXiσjY)Xσj1Zaj12(i=j+1N(σiXX))(σjX+iσjY)Xσj1Z
返回:

QubitOperator,经过宇称变换后的玻色子算符。

reversed_jordan_wigner()[源代码]

应用Jordan-Wigner逆变换。

返回:

FermionOperator,Jordan-Wigner逆变换后的费米子算符。

ternary_tree()[源代码]

作用Ternary tree变换。 基于 Optimal fermion-to-qubit mapping via ternary trees with applications to reduced quantum states learning 实现。

返回:

QubitOperator,Ternary tree变换后的玻色子算符。

class mindquantum.algorithm.nisq.UCCAnsatz(n_qubits=None, n_electrons=None, occ_orb=None, vir_orb=None, generalized=False, trotter_step=1)[源代码]

用于分子模拟的幺正耦合簇。

U(θ)=j=1N(N1)i=0Njexp(θiτ^i)

其中,τ^ 是反厄米算符。

说明

目前,该电路是使用JW变换构建的。 此外,不包括参考状态波函数(Hartree-Fock)。

参数:
  • n_qubits (int) - 量子比特(自旋轨道)的数量。默认值:None。

  • n_electrons (int) - 电子的数量(占用的自旋轨道)。默认值:None。

  • occ_orb (list) - 手动分配的占用空间轨道的索引,仅适用于ansatz构造。默认值:None。

  • vir_orb (list) - 手动分配的虚拟空间轨道的索引,仅适用于ansatz构造。默认值:None。

  • generalized (bool) - 是否使用不区分占用轨道或虚拟轨道的广义激励(UCCGSD)。默认值:False。

  • trotter_step (int) - Trotterization的阶数。默认值:1。

样例:

>>> from mindquantum.algorithm.nisq import UCCAnsatz
>>> ucc = UCCAnsatz(12, 4, occ_orb=[1],
...                 vir_orb=[2, 3],
...                 generalized=True,
...                 trotter_step=2)
>>> circuit = ucc.circuit.remove_barrier()
>>> len(circuit)
3624
>>> params_list = ucc.circuit.params_name
>>> len(params_list)
48
>>> circuit[-10:]
q5: ──●────RX(7π/2)───────H───────●────────────────────────────●───────H──────
      │                           │                            │
q7: ──X───────H────────RX(π/2)────X────RZ(-0.5*t_1_d0_d_17)────X────RX(7π/2)──
mindquantum.algorithm.nisq.generate_uccsd(molecular, threshold=0)[源代码]

使用OpenFermion生成的分子数据生成uccsd量子线路。

参数:
  • molecular (Union[str, MolecularData]) - 分子数据文件的名称,或openfermion中的 MolecularData

  • threshold (float) - 过滤uccsd中组态幅度的阈值。我们将保留那些组态振幅绝对值比 threshold 大的组态,因此,当 threshold=0 时,只会保留非零振幅的组态。默认值:0。

返回:
  • uccsd_circuit (Circuit) - 由uccsd方法生成的ansatz电路。

  • initial_amplitudes (numpy.ndarray) - uccsd电路的初始参数值。

  • parameters_name (list[str]) - 初始参数的名称。

  • qubit_hamiltonian (QubitOperator) - 分子的哈密顿量。

  • n_qubits (int) - 模拟中使用的量子比特数。

  • n_electrons (int) - 分子的电子数。

mindquantum.algorithm.nisq.get_qubit_hamiltonian(mol)[源代码]

获取分子数据的哈密顿量。

参数:
  • mol (MolecularData) - 分子数据。

返回:

QubitOperator,此分子的玻色子算符。

mindquantum.algorithm.nisq.quccsd_generator(n_qubits=None, n_electrons=None, anti_hermitian=True, occ_orb=None, vir_orb=None, generalized=False)[源代码]

使用比特激发算符生成 qubit-UCCSD (qUCCSD) ansatz。

说明

当前版本为无限制版本,即同一空间轨道但具有不同自旋的激发算符使用不同的变分参数。

参数:
  • n_qubits (int) - 量子比特(自旋轨道)的数量。默认值:None。

  • n_electrons (int) - 电子的数量(占据自旋轨道)。默认值:None。

  • anti_hermitian (bool) - 是否减去厄米共轭以形成反厄米算符。默认值:True。

  • occ_orb (list) - 手动分配的占据空间轨道的序号。默认值:None。

  • vir_orb (list) - 手动分配的虚空间轨道的序号。默认值:None。

  • generalized (bool) - 是否使用不区分占据轨道和虚轨道的广义激发算符(qUCCGSD)。默认值:False。

返回:

QubitExcitationOperator,qUCCSD算符。

样例:

>>> from mindquantum.algorithm.nisq import quccsd_generator
>>> quccsd_generator()
0
>>> quccsd_generator(4, 2)
-1.0*q_s_0 [Q0^ Q2] +
-1.0*q_s_2 [Q0^ Q3] +
-1.0*q_d_0 [Q1^ Q0^ Q3 Q2] +
-1.0*q_s_1 [Q1^ Q2] +
-1.0*q_s_3 [Q1^ Q3] +
1.0*q_s_0 [Q2^ Q0] +
1.0*q_s_1 [Q2^ Q1] +
1.0*q_s_2 [Q3^ Q0] +
1.0*q_s_3 [Q3^ Q1] +
1.0*q_d_0 [Q3^ Q2^ Q1 Q0]
>>> q_op = quccsd_generator(occ_orb=[0], vir_orb=[1], generalized=True)
>>> q_qubit_op = q_op.to_qubit_operator()
>>> print(str(q_qubit_op)[:315])
0.125*I*q_d_4 + 0.125*I*q_d_7 + 0.125*I*q_d_9 [X0 X1 X2 Y3] +
0.125*I*q_d_4 - 0.125*I*q_d_7 - 0.125*I*q_d_9 [X0 X1 Y2 X3] +
0.25*I*q_d_12 + 0.25*I*q_d_5 + 0.5*I*q_s_0 - 0.5*I*q_s_3 [X0 Y1] +
-0.125*I*q_d_4 + 0.125*I*q_d_7 - 0.125*I*q_d_9 [X0 Y1 X2 X3] +
0.125*I*q_d_4 + 0.125*I*q_d_7 - 0.125*I*q_d_9 [X0 Y1 Y2 Y3] +
mindquantum.algorithm.nisq.uccsd0_singlet_generator(n_qubits=None, n_electrons=None, anti_hermitian=True, occ_orb=None, vir_orb=None, generalized=False)[源代码]

利用CCD0 ansatz来生成分子系统的UCCSD算子。

说明

手动配置的 occ_orb 或者 vir_orb 会被认为是空间轨道而不是自选轨道,并且会重新改写 n_electronsn_qubits。 这在某种程度上与活动空间相似,因此可以减少变分参数的数量。但是,它可能不会减少所需要的比特数,因为费米子激发算符是非局部的,例如, a7a0 不仅涉及第0和第7个量子比特,而且还涉及第1个直到第6个量子比特。

参数:
  • n_qubits (int) - 量子比特个数(自旋轨道)。默认值:None。

  • n_electrons (int) - 电子个数(占据的自旋轨道)。默认值:None。

  • anti_hermitian (bool) - 是否减去该算符的厄米共轭以形成反厄米共轭算符。默认值:True。

  • occ_orb (list) - 手动分配的占据空间轨道的序号。默认值:None。

  • vir_orb (list) - 手动分配的虚空间轨道的序号。默认值:None。

  • generalized (bool) - 是否使用不区分占据轨道或虚轨道的广义激发(UCCGSD)。默认值:False。

返回:

FermionOperator,使用CCD0 ansatz生成的UCCSD算子。

样例:

>>> from mindquantum.algorithm.nisq import uccsd0_singlet_generator
>>> uccsd0_singlet_generator(4, 2)
-1.0*d0_s_0 [0^ 2] +
2.0*d0_d_0 [1^ 0^ 3 2] +
-1.0*d0_s_0 [1^ 3] +
1.0*d0_s_0 [2^ 0] +
1.0*d0_s_0 [3^ 1] +
-2.0*d0_d_0 [3^ 2^ 1 0]
>>> uccsd0_singlet_generator(4, 2, generalized=True)
1.0*d0_s_0 - 1.0*d0_s_1 [0^ 2] +
1.0*d0_d_0 [1^ 0^ 2 1] +
-1.0*d0_d_0 [1^ 0^ 3 0] +
-2.0*d0_d_1 [1^ 0^ 3 2] +
1.0*d0_s_0 - 1.0*d0_s_1 [1^ 3] +
-1.0*d0_s_0 + 1.0*d0_s_1 [2^ 0] +
-1.0*d0_d_0 [2^ 1^ 1 0] +
1.0*d0_d_2 [2^ 1^ 3 2] +
1.0*d0_d_0 [3^ 0^ 1 0] +
-1.0*d0_d_2 [3^ 0^ 3 2] +
-1.0*d0_s_0 + 1.0*d0_s_1 [3^ 1] +
2.0*d0_d_1 [3^ 2^ 1 0] +
-1.0*d0_d_2 [3^ 2^ 2 1] +
1.0*d0_d_2 [3^ 2^ 3 0]
>>> uccsd0_singlet_generator(6, 2, occ_orb=[0], vir_orb=[1])
-1.0*d0_s_0 [0^ 2] +
2.0*d0_d_0 [1^ 0^ 3 2] +
-1.0*d0_s_0 [1^ 3] +
1.0*d0_s_0 [2^ 0] +
1.0*d0_s_0 [3^ 1] +
-2.0*d0_d_0 [3^ 2^ 1 0]
mindquantum.algorithm.nisq.uccsd_singlet_generator(n_qubits, n_electrons, anti_hermitian=True)[源代码]

n_electrons 的系统生成单态UCCSD算子。此函数生成一个由费米子构成的UCCSD算子,该算子作用在一个由 n_qubits 的自旋轨道和 n_electrons 电子构成的单参考态,也就是自旋单态算符,这也意味着该算符能够保证自旋守恒。

参数:
  • n_qubits (int) - 用于表示系统的自旋轨道数,这也对应于非紧凑映射中的量子比特数。

  • n_electrons (int) - 物理系统中电子数。

  • anti_hermitian (bool) - 仅生成普通CCSD运算符而不是幺正的形式,主要用于测试。

返回:

FermionOperator,构建UCCSD波函数的UCCSD算子。

样例:

>>> from mindquantum.algorithm.nisq.chem import uccsd_singlet_generator
>>> uccsd_singlet_generator(4, 2)
-s_0 [0^ 2] +
-d1_0 [0^ 2 1^ 3] +
-s_0 [1^ 3] +
-d1_0 [1^ 3 0^ 2] +
s_0 [2^ 0] +
d1_0 [2^ 0 3^ 1] +
s_0 [3^ 1] +
d1_0 [3^ 1 2^ 0]
mindquantum.algorithm.nisq.uccsd_singlet_get_packed_amplitudes(single_amplitudes, double_amplitudes, n_qubits, n_electrons)[源代码]

提取单态UCCSD算子的振幅系数。输出列表仅包含与单态UCCSD相关的振幅,顺序与 uccsd_singlet_generator 保持一致。

参数:
  • single_amplitudes (numpy.ndarray) - N×N 维的数组,该数组存储着 ti,j(aiajH.C.) 和对应的排序好的单激发算符的振幅。

  • double_amplitudes (numpy.ndarray) - N×N×N×N 数组,该数组存储着 ti,j,k,l(aiajakalH.C.) 和对应的排序好的双激发算符的振幅。

  • n_qubits (int) - 用于表示系统的自旋轨道数,这也对应于非紧凑映射中的量子比特数。

  • n_electrons (int) - 物理系统中电子的数量。

返回:

ParameterResolver,存储着所有单激发态和双激发态算符的系数。在返回的系数中,单激发态系数位于双激发态之前。

样例:

>>> import numpy as np
>>> from mindquantum.algorithm.nisq.chem import uccsd_singlet_get_packed_amplitudes
>>> n_qubits, n_electrons = 4, 2
>>> np.random.seed(42)
>>> ccsd_single_amps = np.random.random((4, 4))
>>> ccsd_double_amps = np.random.random((4, 4, 4, 4))
>>> uccsd_singlet_get_packed_amplitudes(ccsd_single_amps, ccsd_double_amps,
...                                     n_qubits, n_electrons)
{'d1_0': 0.76162, 's_0': 0.601115}, const: 0