Teitur Hansen, Jens Jørgen Mortensen, Thomas Bligaard, and Karsten Wedel Jacobsen
Uncertainty-aware electronic density-functional distributions.
Phys. Rev. B 112, 075412
Teitur Hansen, Jens Jørgen Mortensen, Thomas Bligaard, and Karsten Wedel Jacobsen
Uncertainty-aware electronic density-functional distributions.
Phys. Rev. B 112, 075412
Download ASE database: uafd.db
Fabien Tran, Julia Stelzl and Peter Blaha
Chem. Phys. 144, 204120 (2016)
import numpy as np
# Functionals of interest and
# functional that is subtracted from others to fulfill sum rule.
functionals = ['PBE', 'RPBE', 'BLYP', 'PBEsol', 'LDA']
functionals_no_pbe = ['RPBE', 'BLYP', 'PBEsol', 'LDA']
func_shift = 'PBE'
# Parameters for distribution of models from
# "Teitur Hansen, Jens Jørgen Mortensen, Thomas Bligaard,
# and Karsten Wedel Jacobsen,
# Uncertainty-aware electronic density-functional distributions.
# Phys. Rev. B 112, 075412"
w0 = np.array([4.69, -1.45, -2.22, 1.71])
K = np.array([[11.05, -7.43, -17.14, 7.83],
[-7.43, 5.47, 14.24, -6.13],
[-17.14, 14.24, 43.67, -17.65],
[7.83, -6.13, -17.65, 7.33]])
# Example data - Atomization energy of LiH
ae = {'PBE': -1.158,
'RPBE': -1.157,
'BLYP': -1.271,
'PBEsol': -1.179,
'LDA': -1.320,
'EXP': -1.258}
ae_exp = round(ae['EXP'], 3)
# To fulfill sum rule we subtract all results by PBE
# and remove the PBE entry from the dataset
ae_shifted = {f: ae[f] - ae[func_shift] for f in functionals}
ae_shifted.pop(func_shift)
# Now we make a prediction using w0 and K
phi = np.array([ae_shifted[f] for f in functionals_no_pbe])
ae_uafd = phi.T @ w0
ae_uncertainty = np.sqrt(phi.T @ K @ phi)
# Shift prediction back
ae_uafd = ae_uafd + ae['PBE']
# Round the results for readability
ae_uafd = round(ae_uafd, 3)
ae_uncertainty = round(ae_uncertainty, 3)
ae_error = round(ae_uafd - ae_exp, 3)
print('-- Atomization energies of LiH --')
print(f'Predicted: {ae_uafd} eV/atom')
print(f'Experimental: {ae_exp} eV/atom')
print('\n-- Uncertainty and error in atomization energy of LiH --')
print(f'Uncertainty: {ae_uncertainty} eV/atom')
print(f'Error: {ae_error} eV/atom')
# Calculate uncertainty for a specific functional
functional_choice = 'LDA'
ae_f = ae[functional_choice]
ae_f_error = ae_f - ae_exp
ae_f_uncertainty = np.sqrt(ae_uncertainty**2 + (ae_uafd - ae_f)**2)
print(f'\n-- Uncertainty and error using {functional_choice} --')
print(f'{functional_choice} prediction: {ae_f} eV/atom')
print(f'{functional_choice} error: {ae_f_error} eV/atom')
print(f'{functional_choice} uncertainty: {ae_f_uncertainty} eV/atom')
Output:
-- Atomization energies of LiH --
Predicted: -1.22 eV/atom
Experimental: -1.258 eV/atom
-- Uncertainty and error in atomization energy of LiH --
Uncertainty: 0.066 eV/atom
Error: 0.038 eV/atom
-- Uncertainty and error using LDA --
LDA prediction: -1.32 eV/atom
LDA error: -0.062000000000000055 eV/atom
LDA uncertainty: 0.11981652640600135 eV/atom