qat.fermion.chemistry.wrapper.MolecularHamiltonian

class qat.fermion.chemistry.wrapper.MolecularHamiltonian(one_body_integrals: ndarray, two_body_integrals: ndarray, constant_coeff: ndarray)

MolecularHamiltonian helper class. It represents the electronic-structure Hamiltonian defined using one- and two-body integrals.

This electronic-structure Hamiltonian is defined by:

\[H=\sum_{uv\sigma}I_{uv}c^{\dagger}_{u\sigma}c_{v\sigma}+\frac{1}{2}\sum_{uvwx}\sum_{\sigma \sigma'} I_{uvwx}c^{\dagger}_{u\sigma}c^{\dagger}_{v\sigma'}c_{w\sigma'}c_{x\sigma}+r\mathbb{I}\]

with \(r\) the core repulsion constant, and with \(I_{uv}\) and \(I_{uvwx}\) the one- and two-body integrals defined by:

\[ \begin{align}\begin{aligned}I_{uv} = \int dr \phi^{*}_{u}(r)h_{1}[\phi_{v}(r)]\\I_{uvwx} = \int dr dr' \phi^{*}_{u}(r)\phi^{*}_{v}(r')v[\phi_{w}(r)\phi_{x}(r')]\end{aligned}\end{align} \]

Here, \(\{\phi_{i}(r)\}_{i=0...N-1}\) is the single-particle basis, with \(N\) the size, which depends on the basis chosen. \(h_{1} = h_{kin} + h_{pot}\) is the one-body Hamiltonian, and \(v\) the Coulomb operator.

Note

This electronic-structure Hamiltonian definition is different than the one used in ElectronicStructureHamiltonian.

Parameters
  • one_body_integrals (np.ndarray) – One-body integral \(I_{uv}\).

  • two_body_integrals (np.ndarray) – Two-body integral \(I_{uvwx}\).

  • constant_coeff (np.ndarray) – Constant coefficient \(r\) (core repulsion).

nqbits

The total number of qubits.

Type

int

one_body_integrals

One-body integral \(I_{uv}\).

Type

np.ndarray

two_body_integrals

Two-body integral \(I_{uvwx}\).

Type

np.ndarray

constant_coeff

Constant coefficient \(r\) (core repulsion).

Type

np.ndarray

Example

import numpy as np
from qat.fermion.chemistry import MolecularHamiltonian

# Initialize random one- and two-body integrals, and a constant
one_body_integral = np.random.randn(2, 2)
two_body_integral = np.random.randn(2, 2, 2, 2)
constant = np.random.rand()

# Define the MolecularHamiltonian
mol_h = MolecularHamiltonian(one_body_integral, two_body_integral, constant)

print(mol_h)
 MolecularHamiltonian(
 - constant_coeff : 0.7620867383741117
 - integrals shape
    * one_body_integrals : (2, 2)
    * two_body_integrals : (2, 2, 2, 2)
)
get_electronic_hamiltonian() ElectronicStructureHamiltonian

Converts the MolecularHamiltonian to an ElectronicStructureHamiltonian. To do so, it converts from \(I_{uv},I_{uvwx}\) to \(h_{pq},h_{pqrs}\), with

\[ \begin{align}\begin{aligned}h_{u\sigma, v\sigma'} = I_{u, v} \delta_{\sigma, \sigma'}\\h_{u\sigma_1, v\sigma_2, w\sigma_2', x\sigma_1'} = I_{uvwx} \left((1-\delta_{\sigma,\sigma'}) + \delta_{\sigma,\sigma'} (1-\delta_{u,v})(1-\delta_{w,x}) \right)\end{aligned}\end{align} \]

and where the one- and two-body integrals are defined as:

\[I_{uv}\equiv(u|h|v)=\int\mathrm{d}r\phi_{u}^{*}(r)T\phi_{v}(r)\]
\[I_{uvwx}\equiv(ux|vw)=\iint\mathrm{d}r_{1}\mathrm{d}r_{2}\phi_{u}^{*}(r_{1})\phi_{x}(r_{1})v(r_{12})\phi_{v}^{*}(r_{2})\phi_{w}(r_{2})\]

with \(T\) (resp. \(v\)) the one- (resp. two-) body potentials, and \(\phi_u(r)\) is the molecular orbital wavefunction.

The \(h\) integrals are used to construct hamiltonians of the ElectronicStructureHamiltonian type.

Returns

ElectronicStructureHamiltonian Electronic structure hamiltonian.

select_active_space(noons: List[float], n_electrons: int, threshold_1: Optional[float] = 0.02, threshold_2: Optional[float] = 0.001) Tuple[MolecularHamiltonian, List[int], List[int]]

Selects the right active space and freezes core electrons according to their NOONs \(n_i\).

This function is an implementation of the Complete Active Space (CAS) approach. It divides orbital space into sets of active and inactive orbitals, the occupation number of the latter remaining unchanged during the computation.

The active space indices are defined as:

\[\mathcal{A} = \{i, n_i \in [\varepsilon_2, 2 - \varepsilon_1[\} \cup \{i, n_i \geq 2-\varepsilon_1, 2(i+1)\geq N_e \}\]

The inactive occupied orbitals are defined as:

\[\mathcal{O} = \{i, n_i \geq 2 -\varepsilon_1, 2(i+1) < N_e \}\]

The restriction of the one- and two-body integrals (and update of the core energy) is then carried out according to:

\[\forall u,v \in \mathcal{A},\; I^{(a)}_{uv} = I_{uv} + \sum_{i\in \mathcal{O}} 2 I_{i,u,v,i} - I_{i,u,i,v}\]
\[\forall u,v,w,x \in \mathcal{A}, I^{(a)}_{uvwx} = I_{uvwx}\]
\[E_\mathrm{core}^{(a)} = E_\mathrm{core} + \sum_{i\in\mathcal{O}} I_{ii} + \sum_{ij\in\mathcal{O}} 2 I_{ijji} - I_{ijij}\]
Parameters
  • noons (List[float]) – the natural-orbital occupation numbers \(n_i\), sorted in descending order (from high occupations to low occupations)

  • n_electrons (int) – The number of electrons \(N_e\).

  • threshold_1 (Optional[float]) – The upper threshold \(\varepsilon_1\) on the NOON of an active orbital.

  • threshold_2 (Optional[float]) – The lower threshold \(\varepsilon_2\) on the NOON of an active orbital.

Returns

  • the molecular Hamiltonian in active space \(H^{(a)}\)

  • the list of indices corresponding to the active orbitals, \(\mathcal{A}\)

  • the list of indices corresponding to the occupied orbitals, \(\mathcal{O}\)

Return type

Tuple[MolecularHamiltonian, List[int], List[int]]

transform_basis(transformation_matrix: ndarray) MolecularHamiltonian

Change one and two body integrals (indices p, q…) to new basis (indices i, j…) using transformation U such that

\[\hat{c}_{i}=\sum_{q}U_{qi}c_{q}\]

i.e

\[ \begin{align}\begin{aligned}\hat{I}_{ij} =\sum_{pq}U_{pi}I_{pq}U_{jq}^{\dagger}\\\hat{I}_{ijkl}=\sum_{pqrs}U_{pi}U_{qj}I_{pqrs}U_{kr}^{\dagger}U_{ls}^{\dagger}\end{aligned}\end{align} \]
Parameters

transformation_matrix (np.array) – transformation matrix \(U\)

Returns

MolecularHamiltonian updated to the new basis.

Return type

molecular_hamiltonian (MolecularHamiltonian)