A free, opensource python package for quickly and precisely approximating FermiDirac integrals.
Project description
FermiDirac Integrals (FDINT)
FDINT is a free, opensource python package that provides fast, double precision (64bit floating point) approximations to the FermiDirac integrals of integer and half integer order, based on the work by Prof. Fukushima [13]. FDINT is written predominantly in Cython, which is compiled to native code through an intermediate C source, resulting in Clike performance.
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 FermiDirac integral and derivative convenience functions, fdk and dfdk:
>>> fdk(k=0.5,phi=10) 4.0233994366893939e05 >>> fdk(0.5,10) 4.0233994366893939e05 >>> 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.0233348580568672e05
You can also pass in numpy arrays as phi:
>>> import numpy >>> fdk(k=0.5,phi=numpy.linspace(100,10,3)) array([ 3.29683149e44, 2.53684104e20, 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 FermiDirac 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 FermiDirac 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 FermiDirac 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 ~517x 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.
Source Distribution
Built Distributions
Hashes for fdint2.0.2cp38cp38win_amd64.whl
Algorithm  Hash digest  

SHA256  5275ba6643c9755ff83b22957d512e4b0bce6ec2b4fb0078d3f7155c439e29b8 

MD5  01d5f6514c415d9488c28f6eed7a5f64 

BLAKE2b256  f6bfbee3a4ede7526ea36a219c2ac2d5960da2692cdcede215732190064c4fee 
Hashes for fdint2.0.2cp36cp36mwin_amd64.whl
Algorithm  Hash digest  

SHA256  dfb6ec5eaa55d6dee5ac6b179741ebc6f32cb9c50473b5c13761fe473d9d66a7 

MD5  19785543fe4e24a9f719a836db45f933 

BLAKE2b256  fa244e2a52c3f30d07bccbe101f922581b715e0f91e359ff05e6b057f02ac0a1 