mindquantum.algorithm.nisq.QubitUCCAnsatz

View Source On Gitee
class mindquantum.algorithm.nisq.QubitUCCAnsatz(n_qubits=None, n_electrons=None, occ_orb=None, vir_orb=None, generalized=False, trotter_step=1)[source]

Qubit Unitary Coupled-Cluster (qUCC) ansatz class.

Qubit Unitary Coupled-Cluster (qUCC) ansatz is a variant of unitary coupled-cluster ansatz which uses qubit excitation operators instead of Fermion excitation operators. The Fock space spanned by qubit excitation operators is equivalent as Fermion operators, therefore the exact wave function can be approximated using qubit excitation operators at the expense of a higher order of Trotterization.

The greatest advantage of qUCC is that the number of CNOT gates is much smaller than the original version of UCC, even using a 3rd or 4th order Trotterization. Also, the accuracy is greatly improved despite that the number of variational parameters is increased.

Note

The Hartree-Fock circuit is not included. Currently, generalized=True is not allowed since the theory needs verification. Reference: Efficient quantum circuits for quantum computational chemistry.

Parameters
  • n_qubits (int) – The number of qubits (spin-orbitals) in the simulation. Default: None.

  • n_electrons (int) – The number of electrons of the given molecule. Default: None.

  • occ_orb (list) – Indices of manually assigned occupied spatial orbitals. Default: None.

  • vir_orb (list) – Indices of manually assigned virtual spatial orbitals. Default: None.

  • generalized (bool) – Whether to use generalized excitations which do not distinguish occupied or virtual orbitals (qUCCGSD). Currently, generalized=True is not allowed since the theory needs verification. Default: False.

  • trotter_step (int) – The number of Trotter steps. It is recommended to set a value larger than or equal to 2 to achieve a good accuracy. Default: 1.

Examples

>>> from mindquantum.algorithm.nisq import QubitUCCAnsatz
>>> QubitUCCAnsatz().n_qubits
0
>>> qucc = QubitUCCAnsatz(4, 2, trotter_step=2)
>>> qucc.circuit[:6]
      ┏━━━┓                   ┏━━━┓
q0: ──┨╺╋╸┠─────────■─────────┨╺╋╸┠─────────────────────────────────
      ┗━┳━┛         ┃         ┗━┳━┛
        ┃           ┃           ┃   ┏━━━┓                   ┏━━━┓
q2: ────╂───────────╂───────────╂───┨╺╋╸┠─────────■─────────┨╺╋╸┠───
        ┃           ┃           ┃   ┗━┳━┛         ┃         ┗━┳━┛
        ┃   ┏━━━━━━━┻━━━━━━━┓   ┃     ┃   ┏━━━━━━━┻━━━━━━━┓   ┃
q1: ────■───┨ RY(t_0_q_s_0) ┠───■─────■───┨ RY(t_0_q_s_1) ┠───■─────
            ┗━━━━━━━━━━━━━━━┛             ┗━━━━━━━━━━━━━━━┛
>>> 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] ]