BFit is a python program that is used to fit a convex sum of positive basis functions to any probability distribution.
Primarily intended for quantum chemistry community, where the basis functions are Gaussian functions and the fitted probability distribution is the electron density.
The features of this software are:
-
Gaussian Basis sets:
- Handle S-type and P-type Gaussian functions.
- Handle Atomic Densities or Molecular Densities.
- Handle any dimensions.
-
Fitting Measures:
- Least-squares method,
- Kullback-Leibler method.
-
Optimization Procedures
- Optimize using "scipy.minimize" procedures.
- Optimize Kullback-Leibler using self-consistent iterative method see paper.
-
Construct Slater atomic densities, including anions, cations and heavy elements, see data page.
- Python >= 3.0: http://www.python.org/
- NumPy >= 1.18.5: http://www.numpy.org/
- SciPy >= 1.5.0: http://www.scipy.org/
- PyTest >= 5.3.4: https://docs.pytest.org/
- PyTest-Cov >= 2.8.0: https://pypi.org/project/pytest-cov/
- PIP >= 19.0: https://pip.pypa.io/
In your terminal run:
git clone https://github.com/QuantumElephant/fitting.git
python ./setup.py install
Run tests to see if it's installed properly:
pytest -v fitting
There are four steps to using BFit.
The grid is a uniform one-dimension grid with 100 points from 0. to 50.
from bfit.grid import UniformRadialGrid
grid = UniformRadialGrid(num_pts=100, min_radii=0., max_radii=50.)
See grid.py, for different assortment of grids.
Here, the model distribution is 5 S-type, normalized Gaussian functions with center at the origin.
from bfit.model import AtomicGaussianDensity
model = AtomicGaussianDensity(grid.points, num_s=5, num_p=0, normalize=True)
See model.py for more options of Gaussian models.
The algorithm is fitted based on the paper.
from bfit.fit import KLDivergenceSCF
# What you want fitted to should also be defined on `grid.points`.
density = np.array([...])
fit = KLDivergenceSCF(grid, density, model)
See fit.py for options of fitting algorithms.
# Provide Initial Guesses
c0 = np.array([1., 1., 1., 1.])
e0 = np.array([0.001, 0.1, 1., 5., 100.])
# Optimize both coefficients and exponents.
result = fit.run(c0, e0, opt_coeffs=True, opt_expons=True, maxiter=1000)
print("Optimized coefficients are: ", result["x"][0])
print("Optimized exponents are: ", result["x"][1])
print("Final performance measures are: ", result["performance"][-1])
print("Was it successful? ", result["success"])
See the example directory for more examples.
Please cite the following. TODO: Update PAPER
Alireza Tehrani, Farnaz Heidar-Zadeh, James S.M. Anderson, Toon Verstraelen, Rogelio Cuevas-Saavedra, Ivan Vinogradov, Debajit Chakraborty, Paul W. Ayers. "BFit: Information-Theoretic Approach to Basis-Set Fitting of Electron Densities"
Please see Data Readme in the data folder.