mindquantum.ansatz
Implementation of different ansatz.
- class mindquantum.ansatz.Ansatz(name, n_qubits, *args, **kwargs)[source]
Basic class for Ansatz.
- Parameters
- property circuit
Get the quantum circuit of this ansatz.
- Returns
Circuit, the quantum circuit of this ansatz.
- class mindquantum.ansatz.HardwareEfficientAnsatz(n_qubits, single_rot_gate_seq, entangle_gate=X, entangle_mapping='linear', depth=1)[source]
Hardware efficient ansatz is a kind of ansatz that can be easily implement on quantum chip.
The hardware efficient is constructed by a layer of single qubit rotation gate and a layer of two qubits entanglement gate. The single qubit rotation gate layer is constructed by one or several rotation gate that act on every qubit. The two qubits entanglement gate layer is constructed by CNOT, CZ, XX, YY, ZZ, etc. acting on entangle_mapping. For more detail, please refers https://www.nature.com/articles/nature23879.
- Parameters
n_qubits (int) – number of qubit that this ansatz act on.
single_rot_gate_seq (list[BasicGate]) – A list of parameterized rotation gate that act on each qubit.
entangle_gate (BasicGate) – The non parameterized entanglement gate. If it is a single qubit gate, than the control version will be used. Default: XGate.
entangle_mapping (Union[str, list[tuple[int]]]) – The entanglement mapping of entanglement gate. ‘linear’ means the entanglement gate will be act on every neighboring qubits. ‘all’ means the entanglemtn gate will be act on any two qbuits. Besides, you can specific which two qubits you want to do entanglement by setting the entangle_mapping to a list of two qubits tuple. Default: “linear”.
depth (int) – Repeat the entanglement gate layer and single_rot_gate_seq in depth times. Default: 1.
Examples
>>> from mindquantum.ansatz import HardwareEfficientAnsatz >>> from mindquantum import RY, RZ, Z >>> hea = HardwareEfficientAnsatz(3, [RY, RZ], Z, [(1, 0), (2, 0)]) >>> hea.circuit RY(d0_n0_0|0) RZ(d0_n0_1|0) RY(d0_n1_0|1) RZ(d0_n1_1|1) RY(d0_n2_0|2) RZ(d0_n2_1|2) Z(1 <-: 0) Z(2 <-: 0) RY(d1_n0_0|0) RZ(d1_n0_1|0) RY(d1_n1_0|1) RZ(d1_n1_1|1) RY(d1_n2_0|2) RZ(d1_n2_1|2)
- class mindquantum.ansatz.Max2SATAnsatz(clauses, depth=1)[source]
The Max-2-SAT ansatz. For more detail, please refers to https://arxiv.org/pdf/1906.11259.pdf.
\[U(\beta, \gamma) = e^{-\beta_pH_b}e^{-\gamma_pH_c} \cdots e^{-\beta_0H_b}e^{-\gamma_0H_c}H^{\otimes n}\]Where,
\[H_b = \sum_{i\in n}X_{i}, H_c = \sum_{l\in m}P(l)\]Here \(n\) is the number of Boolean variables and \(m\) is the number of total clauses and \(P(l)\) is rank-one projector.
- Parameters
Examples
>>> from mindquantum.ansatz import Max2SATAnsatz >>> clauses = [(1, 2), (2, -3)] >>> max2sat = Max2SATAnsatz(clauses, 2) >>> max2sat.circuit H(0) H(1) H(2) RZ(0.25*beta_0|0) RZ(0.5*beta_0|1) X(1 <-: 0) RZ(0.5*beta_0|1) X(1 <-: 0) RZ(-0.25*beta_0|2) X(2 <-: 1) RZ(-0.5*beta_0|2) X(2 <-: 1) RX(alpha_0|0) RX(alpha_0|1) RX(alpha_0|2) RZ(0.25*beta_1|0) RZ(0.5*beta_1|1) X(1 <-: 0) RZ(0.5*beta_1|1) X(1 <-: 0) RZ(-0.25*beta_1|2) X(2 <-: 1) RZ(-0.5*beta_1|2) X(2 <-: 1) RX(alpha_1|0) RX(alpha_1|1) RX(alpha_1|2)
>>> max2sat.hamiltonian 0.5 [] + 0.25 [Z0] + 0.25 [Z0 Z1] + 0.5 [Z1] + -0.25 [Z1 Z2] + -0.25 [Z2]
- property hamiltonian
Get the hamiltonian of this max 2 sat problem.
- Returns
QubitOperator, hamiltonian of this max 2 sat problem.
- class mindquantum.ansatz.MaxCutAnsatz(graph, depth=1)[source]
The MaxCut ansatz. For more detail, please refers to https://arxiv.org/pdf/1411.4028.pdf.
\[U(\beta, \gamma) = e^{-\beta_pH_b}e^{-\gamma_pH_c} \cdots e^{-\beta_0H_b}e^{-\gamma_0H_c}H^{\otimes n}\]Where,
\[H_b = \sum_{i\in n}X_{i}, H_c = \sum_{(i,j)\in C}Z_iZ_j\]Here \(n\) is the set of nodes and \(C\) is the set of edges of the graph.
- Parameters
Examples
>>> from mindquantum.ansatz import MaxCutAnsatz >>> graph = [(0, 1), (1, 2), (0, 2)] >>> maxcut = MaxCutAnsatz(graph, 2) >>> maxcut.circuit H(0) H(1) H(2) ZZ(beta_0|0 1) ZZ(beta_0|1 2) ZZ(beta_0|0 2) RX(alpha_0|0) RX(alpha_0|1) RX(alpha_0|2) ZZ(beta_1|0 1) ZZ(beta_1|1 2) ZZ(beta_1|0 2) RX(alpha_1|0) RX(alpha_1|1) RX(alpha_1|2)
>>> maxcut.hamiltonian 1.5 [] + -0.5 [Z0 Z1] + -0.5 [Z0 Z2] + -0.5 [Z1 Z2]
- property hamiltonian
Get the hamiltonian of this max cut problem.
- Returns
QubitOperator, hamiltonian of this max cut problem.
- class mindquantum.ansatz.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 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 advantange 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: Yordan S. Yordanov et al. Phys. Rev. A, 102, 062612 (2020)
- 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. Default is one. It is recommended to set a value larger than or equal to 2 to achieve a good accuracy. Default: 1.
Examples
>>> from mindquantum.ansatz import QubitUCCAnsatz >>> QubitUCCAnsatz().n_qubits 0 >>> qucc = QubitUCCAnsatz(4, 2, trotter_step=2) >>> qucc.circuit[:10] CNOT(0 <-: 2) RY(t_0_q_s_0|2 <-: 0) CNOT(0 <-: 2) CNOT(1 <-: 2) RY(t_0_q_s_1|2 <-: 1) CNOT(1 <-: 2) CNOT(0 <-: 3) RY(t_0_q_s_2|3 <-: 0) CNOT(0 <-: 3) CNOT(1 <-: 3) >>> 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.ansatz.UCCAnsatz(n_qubits=None, n_electrons=None, occ_orb=None, vir_orb=None, generalized=False, trotter_step=1)[source]
The unitary coupled-cluster ansatz for molecular simulations.
\[U(\vec{\theta}) = \prod_{j=1}^{N(N\ge1)}{\prod_{i=0}^{N_{j}}{\exp{(\theta_{i}\hat{\tau}_{i})}}}\]where \(\hat{\tau}\) are anti-Hermitian operators.
Note
Currently, the circuit is construncted using JW transformation. In addition, the reference state wave function (Hartree-Fock) will NOT be included.
- Parameters
n_qubits (int) – Number of qubits (spin-orbitals). Default: None.
n_electrons (int) – Number of electrons (occupied spin-orbitals). Default: None.
occ_orb (list) – Indices of manually assigned occupied spatial orbitals, for ansatz construction only. Default: None.
vir_orb (list) – Indices of manually assigned virtual spatial orbitals, for ansatz construction only. Default: None.
generalized (bool) – Whether to use generalized excitations which do not distinguish occupied or virtual orbitals (UCCGSD). Default: False.
trotter_step (int) – The order of Trotterization step. Default: 1.
Examples
>>> from mindquantum.ansatz import UCCAnsatz >>> ucc = UCCAnsatz(12, 4, occ_orb=[1], ... vir_orb=[2, 3], ... generalized=True, ... trotter_step=2) >>> circuit_list = list(ucc.circuit) >>> len(circuit_list) 3624 >>> params_list = ucc.circuit.para_name >>> len(params_list) 40 >>> for i in range(10): ... print(circuit_list[i]) ... RX(1.571|2) H(4) X(3 <-: 2) X(4 <-: 3) RZ(-1.0*t_0_d0_s_0|4) X(4 <-: 3) X(3 <-: 2) H(4) RX(10.996|2) H(2)