A free, open-source python package for quickly and precisely approximating Fermi-Dirac integrals.

## Project description

## Fermi-Dirac Integrals (FDINT)

FDINT is a free, open-source python package that provides fast, double precision (64-bit floating point) approximations to the Fermi-Dirac integrals of integer and half integer order, based on the work by Prof. Fukushima [1-3]. FDINT is written predominantly in Cython, which is compiled to native code through an intermediate C source, resulting in C-like performance.

[1] | T. Fukushima, “Precise and fast computation of Fermi-Dirac integral of integer and half integer order by piecewise minimax rational approximation,” Applied Mathematics and Computation, vol. 259, pp. 708-729, May 2015. DOI: 10.1016/j.amc.2015.03.009 |

[2] | T. Fukushima, “Precise and fast computation of inverse Fermi-Dirac integral of order 1/2 by minimax rational function approximation,” Applied Mathematics and Computation, vol. 259, pp. 698-707, May 2015. DOI: 10.1016/j.amc.2015.03.015 |

[3] | T. Fukushima, “Precise and fast computation of generalized Fermi-Dirac integral by parameter polynomial approximation,” 2014. DOI: 10.13140/2.1.1094.6566 |

The source code and documentation (coming soon) are graciously hosted by GitHub.

## Installation

In order to use FDINT, you must have a working Python distribution installed. Python 3 support has not yet been tested, so Python 2.7 is suggested. You will also need to install Numpy before proceeding. If you’re not familiar with Python, you might consider installing a Python distribution that comes prepackaged with Numpy.

### From PyPi

This is the recommended method for installing FDINT. PyPi is the python package index, which contains many python packages that can be easily installed with a single command. To install FDINT from PyPi, open up a command prompt and run the following command:

pip install fdint

### From Github

To install the latest release of FDINT from Github, go to the
FDINT releases page, download the latest `.zip` or `.tar.gz`
source package, extract its contents, and run `python setup.py install`
from within the extracted directory.

## Testing

Once installed, you can test the package by running the following command:

python -m fdint.tests

If you have Matplotlib installed, you can also plot a sample of the available functions by running the following command:

python -m fdint.examples.plot

## Tutorial

First, start up an interactive python shell from the command line:

$ python

Next, import everything from the `fdint` package:

>>> from fdint import *

Now you can access the Fermi-Dirac integral and derivative convenience
functions, `fdk` and `dfdk`:

>>> fdk(k=0.5,phi=-10) 4.0233994366893939e-05 >>> fdk(0.5,-10) 4.0233994366893939e-05 >>> fdk(k=0.5,phi=5) 7.837976057293096 >>> fdk(k=0.5,phi=50) 235.81861512588432 >>> dfdk(k=0.5,phi=-10) # first derivative 4.0233348580568672e-05

You can also pass in numpy arrays as phi:

>>> import numpy >>> fdk(k=0.5,phi=numpy.linspace(-100,10,3)) array([ 3.29683149e-44, 2.53684104e-20, 2.13444715e+01])

If you request an order or derivative that is not implemented, a NotImplementedError is raised:

>>> fdk(1,0) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "fdint/__init__.py", line 50, in fdk raise NotImplementedError() NotImplementedError

For semiconductor calculations, `parabolic`, `dparabolic`, `iparabolic`,
`nonparabolic`, and `dnonparabolic` are provided:

>>> parabolic(0) 0.7651470246254078 >>> dparabolic(0) 0.6048986434216304 >>> iparabolic(.7) -0.11156326391089397 >>> nonparabolic(0,0) 0.7651470705342294 >>> nonparabolic(0,0.07) # InAs 1.006986898726782 >>> dnonparabolic(0,0.07) # InAs 0.8190058991462952

## Benchmarks

Below are a few benchmarking runs. First, `numpy.exp`:

$ python -m timeit -s "import numpy; from numpy import exp; x=numpy.linspace(-100,10,10000)" "exp(x)" 10000 loops, best of 3: 72.6 usec per loop

The same arguments to the Fermi-Dirac integral of order k=1/2, `fdint.fd1h`,
takes only ~2.2x the runtime:

$ python -m timeit -s "from fdint import fd1h; import numpy; x=numpy.linspace(-100,10,10000)" "fd1h(x)" 10000 loops, best of 3: 158 usec per loop

Similarly, the inverse Fermi-Dirac integral of order k=1/2, `fdint.ifd1h`,
takes only ~2.4x the runtime of `numpy.log`:

$ python -m timeit -s "import numpy; from numpy import exp,log; x=numpy.linspace(-100,10,10000);y=exp(x)" "log(y)" 10000 loops, best of 3: 69.9 usec per loop $ python -m timeit -s "from fdint import fd1h,ifd1h; import numpy; x=numpy.linspace(-100,10,10000);y=fd1h(x)" "ifd1h(y)" 10000 loops, best of 3: 178 usec per loop

The generalized Fermi-Dirac integrals are also quite fast. For order
k=1/2 with zero nonparabolicity, `fdint.gfd1h` takes only ~3.7x the runtime
of `numpy.exp` for zero nonparabolicity:

$ python -m timeit -s "from fdint import gfd1h; import numpy; x=numpy.linspace(-100,10,10000);b=numpy.zeros(10000);b.fill(0.)" "gfd1h(x,b)" 1000 loops, best of 3: 266 usec per loop

However, if there is significant nonparabolicity, `fdint.gfd1h` can take a
up to ~10x longer than `numpy.exp`:

$ python -m timeit -s "from fdint import gfd1h; import numpy; x=numpy.linspace(-100,10,10000);b=numpy.zeros(10000);b.fill(0.1)" "gfd1h(x,b)" 1000 loops, best of 3: 467 usec per loop $ python -m timeit -s "from fdint import gfd1h; import numpy; x=numpy.linspace(-100,10,10000);b=numpy.zeros(10000);b.fill(0.3)" "gfd1h(x,b)" /usr/local/Cellar/python/2.7.8_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/timeit.py:6: RuntimeWarning: gfd1h: less than 24 bits of accuracy 1000 loops, best of 3: 696 usec per loop

The full calculation for a nonparabolic band takes ~5-17x longer than
`numpy.exp`, depending on the level of nonparabolicity (Note: for
some reason the timing for this command is unreasonably high when timed
from the command line. When timed inside of ipython, it works fine):

$ ipython In [1]: from fdint import * In [2]: import numpy In [3]: phi = numpy.linspace(-100,10,10000) In [4]: %timeit numpy.exp(phi) 10000 loops, best of 3: 72.9 µs per loop In [5]: %timeit parabolic(phi) 10000 loops, best of 3: 165 µs per loop In [6]: alpha = numpy.empty(10000); alpha.fill(0.0) # parabolic In [7]: %timeit nonparabolic(phi, alpha) 1000 loops, best of 3: 346 µs per loop In [8]: alpha = numpy.empty(10000); alpha.fill(0.07) # InAs In [9]: %timeit nonparabolic(phi, alpha) 1000 loops, best of 3: 695 µs per loop In [10]: alpha = numpy.empty(10000); alpha.fill(0.15) # InSb In [11]: %timeit nonparabolic(phi, alpha) /usr/local/bin/ipython:257: RuntimeWarning: nonparabolic: less than 24 bits of accuracy 1000 loops, best of 3: 1.26 ms per loop

## Documentation

The documentation (coming soon) is graciously hosted by GitHub.

## Project details

## Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Filename, size & hash SHA256 hash help | File type | Python version | Upload date |
---|---|---|---|

fdint-2.0.2.tar.gz (704.1 kB) Copy SHA256 hash SHA256 | Source | None |