Ansatz

Qibochem provides functions to construct various chemistry circuit ansatzes.

The easiest way to construct a circuit ansatz for a given qibochem.driver.Molecule is by using the circuit_ansatz() function:

from qibochem.driver import Molecule
from qibochem.ansatz import circuit_ansatz

molecule = Molecule(xyz_file="ch4.xyz")
molecule.run_pyscf()
circuit = circuit_ansatz(molecule, "ucc")

Alternatively, the individual functions can be called to manually construct a circuit ansatz:

from qibochem.driver import Molecule
from qibochem.ansatz import hf_circuit, ucc_circuit

molecule = Molecule(xyz_file="ch4.xyz")
molecule.run_pyscf()
circuit = hf_circuit(molecule.nso, molecule.nelec)
circuit += ucc_circuit(molecule.nso, [8, 9, 10, 11])

More examples can be found in the Tutorial section of the documentation.

qibochem.ansatz.ansatz.circuit_ansatz(molecule: Molecule, ansatz: str, *, excitations: Sequence[Sequence[int]] | None = None, thetas: Sequence[float] | None = None, include_hf: bool = True, **kwargs: dict)

Convenience function for constructing a parameterized quantum circuit ansatz to represent the electronic wave function (using the the Jordan-Wigner fermion to qubit mapping) of a molecular system.

Parameters:
  • molecule (qibochem.driver.Molecule) – Molecule of interest.

  • ansatz (str) –

    Circuit ansatz to be used for the molecule. The possible options are:

    Options:
    • "ucc": Unitary coupled-cluster (UCC) ansatz with a single Trotter step (details)

    • "qeb": Alternative qubit-excitation-based formulation of the UCC ansatz (details)

    • "givens": Givens rotation ansatz (details)

    • "br": Basis rotation ansatz (details)

    • "symm": Symmetry-preserving ansatz (details)

    • "ham": Fixed Hamming-weight ansatz (details)

    Note

    The hardware-efficient circuit ansatz (details) is not included here

  • excitations (Sequence[Sequence[int]] | None, optional) – Fermionic excitations used to build the circuit. If not given, will include all singles and doubles excitations in the circuit by default.

  • thetas (Sequence[float] | None, optional) – Initial parameters for the circuit ansatz. If not given, defaults to MP2 amplitudes for ansatzes involving fermionic excitations ("ucc", "qeb", or "givens"), or a zero array otherwise.

  • include_hf (bool, optional) – Initialise circuit ansatz in a HF reference state if True (default)

  • kwargs (dict, optional) – Additional arguments used to initialize a Circuit object. Details are given in the documentation of qibo.models.circuit.Circuit

Returns:

Circuit corresponding to an UCC ansatz

Return type:

qibo.models.circuit.Circuit

qibochem.ansatz.ansatz.he_circuit(nqubits: int, nlayers: int, rotation_gates: Sequence[str | Gate] | None = None, entangling_gate: str | Gate = 'CNOT', architecture: str = 'diagonal', closed_boundary: bool = True, **kwargs) Circuit

Builds a general hardware-efficient ansatz, in which the rotation and entangling gates used can be chosen by the user. For more details on the arguments related to the entangling layer, see the documentation for qibo.models.encodings.entangling_layer.

Parameters:
  • nqubits (int) – Number of qubits in the quantum circuit.

  • nlayers (int) – Number of layers of rotation and entangling gates.

  • rotation_gates (Sequence[str | Gate] | None, optional) – Single-qubit rotation gates used in the ansatz. These can be given as strings representing valid one-qubit gates, or as qibo.gates.Gate directly. Default: ["RY", "RZ"]

  • entangling_gate (str | Gate, optional) – Two-qubit entangling gate used in the ansatz. This can be given as strings representing valid two-qubit gates, or as a qibo.gates.Gate directly. Default: "CNOT"

  • architecture (str, optional) – Architecture of the entangling layer, with the possible options: "diagonal", "even_layer", "next_nearest", "odd_layer", "pyramid", "shifted", "v", and "x" (defined only for an even number of qubits. Default: "diagonal"

  • closed_boundary (bool, optional) – If True (default) and architecture not in ["pyramid", "v", "x"], adds a closed-boundary condition to the entangling layer

  • kwargs (dict, optional) – Additional arguments used to initialize a Circuit object. Details are given in the documentation of qibo.models.circuit.Circuit

Returns:

Circuit corresponding to the hardware-efficient ansatz

Return type:

qibo.models.circuit.Circuit

qibochem.ansatz.ansatz.hf_circuit(nqubits: int, nelectrons: int, ferm_qubit_map: str = 'jw', **kwargs) Circuit

Quantum circuit to prepare a Hartree-Fock state

Parameters:
  • nqubits (int) – Number of qubits in the quantum circuit

  • nelectrons (int) – Number of electrons in the molecular system

  • ferm_qubit_map (str, optional) – Fermion to qubit map. Must be either Jordan-Wigner ("jw") or Brayvi-Kitaev ("bk"). Default value is "jw".

  • kwargs (dict, optional) – Additional arguments used to initialize a Circuit object. Details are given in the documentation of qibo.models.circuit.Circuit.

Returns:

Circuit initialized in a HF reference state

Return type:

qibo.models.circuit.Circuit

qibochem.ansatz.ansatz.ucc_circuit(nqubits: int, excitation: Sequence[int], theta: float = 0.0, trotter_steps: int = 1, ferm_qubit_map: str = 'jw', **kwargs: dict) Circuit

Quantum circuit corresponding to the unitary coupled-cluster ansatz for a single excitation

Parameters:
  • nqubits (int) – Number of qubits in the quantum circuit

  • excitation (Sequence[int]) – Orbitals involved in the excitation; must have an even number of elements E.g. [0, 1, 2, 3] represents the excitation of electrons in orbitals (0, 1) to (2, 3)

  • theta (float, optional) – UCC parameter. Defaults to 0.0

  • trotter_steps (int, optional) – Number of Trotter steps; i.e. number of times the UCC ansatz is applied with \(\theta = \theta\) / trotter_steps. Default: 1

  • ferm_qubit_map (str, optional) – Fermion-to-qubit transformation. Must be either Jordan-Wigner ("jw") or Brayvi-Kitaev ("bk"). Default value is "jw"

  • kwargs (dict, optional) – Additional arguments used to initialize a Circuit object. Details are given in the documentation of qibo.models.circuit.Circuit

Returns:

Circuit corresponding to a single UCC excitation

Return type:

qibo.models.circuit.Circuit

qibochem.ansatz.ansatz.qeb_circuit(nqubits: int, excitation: Sequence[int], theta: float = 0.0, **kwargs: dict) Circuit

Qubit-excitation-based (QEB) circuit corresponding to the unitary coupled-cluster ansatz for a single excitation. This circuit ansatz is only valid for the Jordan-Wigner fermion to qubit mapping.

Parameters:
  • nqubits (int) – Number of qubits in the quantum circuit

  • excitation (Sequence[int]) – Orbitals involved in the excitation; must have an even number of elements. E.g. [0, 1, 2, 3] represents the excitation of electrons in orbitals (0, 1) to (2, 3)

  • theta (float, optional) – UCC parameter. Defaults to 0.0

  • kwargs (dict, optional) – Additional arguments used to initialize a Circuit object. Details are given in the documentation of qibo.models.circuit.Circuit

Returns:

Circuit corresponding to a single UCC excitation

Return type:

qibo.models.circuit.Circuit

References

1. I. Magoulas and F. A. Evangelista, CNOT-Efficient Circuits for Arbitrary Rank Many-Body Fermionic and Qubit Excitations, Journal of Chemical Theory and Computation, 2023, 19(3), 822-836. (links: here or on arXiv)

qibochem.ansatz.ansatz.givens_circuit(nqubits: int, excitation: Sequence[int], theta: float = 0.0, **kwargs: dict) Circuit

Quantum circuit performing fermionic excitations using Givens rotations.

Parameters:
  • nqubits (int) – Number of qubits in the circuit

  • excitation (Sequence[int]) – Orbitals involved in the excitation; must have an even number of elements E.g. [0, 1, 2, 3] represents the excitation of electrons in orbitals (0, 1) to (2, 3)

  • theta (float, optional) – Rotation angle. Default: 0.0

  • kwargs (dict, optional) – Additional arguments used to initialize a Circuit object. Details are given in the documentation of qibo.models.circuit.Circuit

Returns:

Circuit ansatz for a single Givens rotation

Return type:

qibo.models.circuit.Circuit

References

1. J. M. Arrazola, O. D. Matteo, N. Quesada, S. Jahangiri, A. Delgado, and Nathan Killoran, Universal quantum circuits for quantum chemistry, Quantum, 2022, 6, 742. (link)

qibochem.ansatz.ansatz.basis_rotation_circuit(nqubits: int, nelectrons: int, parameters: Sequence[float] | float | None = None, **kwargs) Circuit

Quantum circuit that performs a basis rotation between the occupied-virtual orbitals using Givens rotations

Parameters:
  • nqubits (int) – Number of qubits in the quantum circuit

  • nelectrons (int) – Number of electrons in the molecular system

  • parameters (Sequence[float] | float | None, optional) – Rotation parameters; must have nelectrons * (nqubits - nelectrons) // 2 elements. Defaults to a zero array if not given

  • kwargs (dict, optional) – Additional arguments used to initialize a Circuit object. Details are given in the documentation of qibo.models.circuit.Circuit.

Returns:

Circuit that performs a unitary rotation between the occupied-virtual

orbitals

Return type:

qibo.models.circuit.Circuit

References

1. Google AI Quantum and Collaborators, Hartree-Fock on a superconducting qubit quantum computer, Science, 2020, 369 (6507), 1084-1089 (link)

qibochem.ansatz.ansatz.symm_preserving_circuit(nqubits: int, nelectrons: int, parameters: Sequence[float] | float | None = None, **kwargs: dict) Circuit

Quantum circuit that preserves particle number, total spin, spin projection, and time-reversal symmetries of the simulated system

Parameters:
  • nqubits (int) – Number of qubits in the quantum circuit

  • nelectrons (int) – Number of electrons in the molecular system

  • parameters (Sequence[float] | float | None, optional) – Rotation parameters; must have \({}^{\text{nqubits}} C_{\text{nelectrons}}\) elements. Defaults to a zero array if not given

  • kwargs (dict, optional) – Additional arguments used to initialize a Circuit object. Details are given in the documentation of qibo.models.circuit.Circuit.

Returns:

Circuit corresponding to the symmetry-preserving ansatz

Return type:

qibo.models.circuit.Circuit

References

1. B. T. Gard, L. Zhu, G. S. Barron, N. J. Mayhall, S. E. Economou, and E. Barnes, Efficient symmetry-preserving state preparation circuits for the variational quantum eigensolver algorithm, npj Quantum Information, 2020, 6, 10. (link)

qibochem.ansatz.ansatz.hamming_weight_circuit(nqubits: int, nelectrons: int, **kwargs: dict) Circuit

Quantum circuit that preserves the Hamming weight (particle number) of the simulated system

Note

This function is a wrapper for the original qibo.models.encodings.hamming_weight_encoder() function in the main Qibo repository.

Parameters:
  • nqubits (int) – Number of qubits in the quantum circuit

  • nelectrons (int) – Number of electrons in the molecular system

  • kwargs (dict, optional) – Additional arguments used to initialize a Circuit object. Details are given in the documentation of qibo.models.circuit.Circuit.

Returns:

Circuit restricted to a fixed Hamming-weight subspace

Return type:

qibo.models.circuit.Circuit

References

1. R. M. S. Farias, T. O. Maciel, G. Camilo, R. Lin, S. Ramos-Calderer, and L. Aolita, Quantum encoder for fixed-Hamming-weight subspaces Phys. Rev. Applied 23, 044014 (2025).

Utility functions

Qibochem also has a few utility functions to assist with the construction of circuit ansatzes.

qibochem.ansatz.utils.generate_excitations(order: int, excite_from: Sequence[int], excite_to: Sequence[int], conserve_spin: bool = True) list[list[int]]

Generate all possible excitations between a list of occupied and virtual orbitals

Parameters:
  • order (int) – Order of excitations, i.e. 1 == single, 2 == double

  • excite_from (Sequence[int]) – Occupied orbitals to excite from

  • excite_to (Sequence[int]) – Virtual orbitals to excite to

  • conserve_spin (bool, optional) – Whether total electronic spin is conserved when generating excitations

Returns:

Generated excitations

Return type:

list[list[int]]

qibochem.ansatz.utils.mp2_amplitude(excitation: Sequence[int], orbital_energies: Sequence[float], tei: ndarray) float

Calculate MP2 guess amplitude for a fermionic excitation. Single excitation will be: 0.0, a double excitation (In SO basis): \(t_{ij}^{ab} = (g_{ijab} - g_{ijba}) / (e_i + e_j - e_a - e_b)\)

Parameters:
  • excitation (Sequence[int]) – Orbitals involved in the excitation. Must have either 2 or 4 elements, representing a single or double excitation respectively

  • orbital_energies (Sequence[float]) – Eigenvalues of the Fock operator, i.e. orbital energies

  • tei (np.ndarray) – Two-electron integrals in MO basis and second quantization notation

Returns:

MP2 guess amplitude

Return type:

float