Skip to content

Commit

Permalink
Add convenience function for all excitations
Browse files Browse the repository at this point in the history
  • Loading branch information
chmwzc committed Aug 1, 2024
1 parent c3847cf commit 29fcafc
Showing 1 changed file with 67 additions and 3 deletions.
70 changes: 67 additions & 3 deletions src/qibochem/ansatz/givens_excitation.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

from qibo import Circuit, gates

from qibochem.ansatz.hf_reference import hf_circuit
from qibochem.ansatz.util import generate_excitations, mp2_amplitude, sort_excitations

# Helper functions


Expand Down Expand Up @@ -81,6 +84,67 @@ def givens_excitation_circuit(n_qubits, excitation, theta=0.0):
return circuit


def givens_excitation_ansatz(n_qubits, excitation, n_electrons):
"""TODO: Same implementation as UCC?"""
pass
def givens_excitation_ansatz(
molecule,
excitation_level=None,
excitations=None,
include_hf=True,
use_mp2_guess=True,
):
"""
Convenience function for buildng a circuit corresponding to the Givens excitation ansatz with multiple excitations
for a given ``Molecule``. If no excitations are given, it defaults to including all possible spin-allowed
excitations, up to doubles.
Args:
molecule: The ``Molecule`` of interest.
excitation_level: Include excitations up to how many electrons, i.e. ``"S"`` or ``"D"``.
Ignored if ``excitations`` argument is given. Default: ``"D"``, i.e. double excitations
excitations: List of excitations (e.g. ``[[0, 1, 2, 3], [0, 1, 4, 5]]``) used to build the
UCC circuit. Overrides the ``excitation_level`` argument
include_hf: Whether or not to start the circuit with a Hartree-Fock circuit. Default: ``True``
use_mp2_guess: Whether to use MP2 amplitudes or a numpy zero array as the initial guess parameter. Default: ``True``;
use the MP2 amplitudes as the default guess parameters
Returns:
Qibo ``Circuit``: Circuit corresponding to the 'Universal' ansatz
"""
# TODO: Consolidate/Meld this function with the ucc_ansatz function; both are largely identical

# Get the number of electrons and spin-orbitals from the molecule argument
n_elec = molecule.nelec if molecule.n_active_e is None else molecule.n_active_e
n_orbs = molecule.nso if molecule.n_active_orbs is None else molecule.n_active_orbs

Check warning on line 116 in src/qibochem/ansatz/givens_excitation.py

View check run for this annotation

Codecov / codecov/patch

src/qibochem/ansatz/givens_excitation.py#L115-L116

Added lines #L115 - L116 were not covered by tests

# Define the excitation level to be used if no excitations given
if excitations is None:
excitation_levels = ("S", "D", "T", "Q")
if excitation_level is None:
excitation_level = "D"

Check warning on line 122 in src/qibochem/ansatz/givens_excitation.py

View check run for this annotation

Codecov / codecov/patch

src/qibochem/ansatz/givens_excitation.py#L119-L122

Added lines #L119 - L122 were not covered by tests
else:
# Check validity of input
assert (

Check warning on line 125 in src/qibochem/ansatz/givens_excitation.py

View check run for this annotation

Codecov / codecov/patch

src/qibochem/ansatz/givens_excitation.py#L125

Added line #L125 was not covered by tests
len(excitation_level) == 1 and excitation_level.upper() in excitation_levels
), "Unknown input for excitation_level"
# Note: Probably don't be too ambitious and try to do 'T'/'Q' at the moment...
if excitation_level.upper() in ("T", "Q"):
raise NotImplementedError("Cannot handle triple and quadruple excitations!")

Check warning on line 130 in src/qibochem/ansatz/givens_excitation.py

View check run for this annotation

Codecov / codecov/patch

src/qibochem/ansatz/givens_excitation.py#L129-L130

Added lines #L129 - L130 were not covered by tests
# Get the (largest) order of excitation to use
excitation_order = excitation_levels.index(excitation_level.upper()) + 1

Check warning on line 132 in src/qibochem/ansatz/givens_excitation.py

View check run for this annotation

Codecov / codecov/patch

src/qibochem/ansatz/givens_excitation.py#L132

Added line #L132 was not covered by tests

# Generate and sort all the possible excitations
excitations = []
for order in range(excitation_order, 0, -1): # Reversed to get higher excitations first
excitations += sort_excitations(generate_excitations(order, range(0, n_elec), range(n_elec, n_orbs)))

Check warning on line 137 in src/qibochem/ansatz/givens_excitation.py

View check run for this annotation

Codecov / codecov/patch

src/qibochem/ansatz/givens_excitation.py#L135-L137

Added lines #L135 - L137 were not covered by tests
else:
# Some checks to ensure the given excitations are valid
assert all(len(_ex) % 2 == 0 for _ex in excitations), "Excitation with an odd number of elements found!"

Check warning on line 140 in src/qibochem/ansatz/givens_excitation.py

View check run for this annotation

Codecov / codecov/patch

src/qibochem/ansatz/givens_excitation.py#L140

Added line #L140 was not covered by tests

# Build the circuit
if include_hf:
circuit = hf_circuit(n_orbs, n_elec) # Only works with (default) JW mapping

Check warning on line 144 in src/qibochem/ansatz/givens_excitation.py

View check run for this annotation

Codecov / codecov/patch

src/qibochem/ansatz/givens_excitation.py#L143-L144

Added lines #L143 - L144 were not covered by tests
else:
circuit = Circuit(n_orbs)
for excitation in excitations:
theta = mp2_amplitude(excitation, molecule.eps, molecule.tei) if use_mp2_guess else None
circuit += givens_excitation_circuit(n_orbs, excitation, theta)
return circuit

Check warning on line 150 in src/qibochem/ansatz/givens_excitation.py

View check run for this annotation

Codecov / codecov/patch

src/qibochem/ansatz/givens_excitation.py#L146-L150

Added lines #L146 - L150 were not covered by tests

0 comments on commit 29fcafc

Please sign in to comment.