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.144723519014625 - 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)