Finite difference weights for any derivative order on arbitrarily spaced grids. C89, C++ and Fortran 90 implementations with Python bindings.
BSD-2-CLAUSE License
.. image:: http://hackspett.bjodah.se/api/badges/12/status.svg :target: http://hackspett.bjodah.se/repos/12 :alt: Build status .. image:: https://img.shields.io/pypi/v/finitediff.svg :target: https://pypi.python.org/pypi/finitediff :alt: PyPI version .. image:: https://zenodo.org/badge/14988640.svg :target: https://zenodo.org/badge/latestdoi/14988640 :alt: Zenodo DOI .. image:: https://img.shields.io/pypi/l/finitediff.svg :target: https://github.com/bjodah/finitediff/blob/master/LICENSE :alt: License .. image:: http://hera.physchem.kth.se/~finitediff/branches/master/htmlcov/coverage.svg :target: http://hera.physchem.kth.se/~finitediff/branches/master/htmlcov :alt: coverage
finitediff
containts three implementations of Begnt Fornberg's
formulae for generation of finite difference weights on aribtrarily
spaced one dimensional grids:
C89 <src/finitediff_c.c>
_Fortran 90 <src/finitediff_fort.f90>
_C++ <finitediff/include/finitediff_templated.hpp>
_The finite difference weights can be used for optimized inter-/extrapolation data series for up to arbitrary derivative order. Python_ bindings (to the C versions) are also provided.
.. _Python: https://www.python.org .. _finitediff: https://github.com/bjodah/finitediff
finitediff
currently provides callbacks for estimation of derivatives
or interpolation either at a single point or over an array (available
from the Python bindings).
The user may also manually generate the corresponding weights. (see
calculate_weights
)
Finitediff can be conditionally compiled to make finitediff_interpolate_by_finite_diff
multithreaded (when FINITEDIFF_OPENMP
is defined). Then the number of threads used is
set through the environment variable FINITEDIFF_NUM_THREADS
(or OMP_NUM_THREADS
).
Autogenerated API documentation for latest stable release is found here:
<https://bjodah.github.io/finitediff/latest>
_
(and the development version for the current master branch is found here:
<http://hera.physchem.kth.se/~finitediff/branches/master/html>
_).
Generating finite difference weights is simple using C++11:
.. code:: C++
#include "finitediff_templated.hpp" #include #include #include
int main(){ const unsigned max_deriv = 2; std::vectorstd::string labels {"0th derivative", "1st derivative", "2nd derivative"}; std::vector x {0, 1, -1, 2, -2}; // Fourth order of accuracy auto coeffs = finitediff::generate_weights(x, max_deriv); for (unsigned deriv_i = 0; deriv_i <= max_deriv; deriv_i++){ std::cout << labels[deriv_i] << ": "; for (unsigned idx = 0; idx < x.size(); idx++){ std::cout << coeffs[deriv_i*x.size() + idx] << " "; } std::cout << std::endl; } }
::
$ cd examples/ $ g++ -std=c++11 demo.cpp -I../include $ ./a.out Zeroth derivative (interpolation): 1 -0 0 0 -0 First derivative: -0 0.666667 -0.666667 -0.0833333 0.0833333 Second derivative: -2.5 1.33333 1.33333 -0.0833333 -0.0833333
and of course using the python bindings:
.. code:: python
from finitediff import get_weights import numpy as np c = get_weights(np.array([0, -1., 1]), 0, maxorder=1) np.allclose(c[:, 1], [0, -.5, .5]) True
from Python you can also use the finite differences to interpolate values (or derivatives thereof):
.. code:: python
>>> from finitediff import interpolate_by_finite_diff as ifd
>>> x = np.array([0, 1, 2])
>>> y = np.array([[2, 3, 5], [3, 4, 7], [7, 8, 9], [3, 4, 6]])
>>> xout = np.linspace(0.5, 1.5, 5)
>>> r = ifd(x, y, xout, maxorder=2)
>>> r.shape
(5, 4, 3)
see the examples/
directory for more examples.
Simplest way to install is to use the conda package manager <http://conda.pydata.org/docs/>
_:
::
$ conda install -c conda-forge finitediff pytest $ python -m pytest --pyargs finitediff
tests should pass.
Manual installation
You can install ``finitediff`` by using ``pip``::
$ python -m pip install --user finitediff
(you can skip the ``--user`` flag if you have got root permissions),
to run the tests you need ``pytest`` too::
$ python -m pip install --user --upgrade pytest
$ python -m pytest --pyargs finitediff
Dependencies
------------
You need either a C, C++ or a Fortran 90 compiler. On debian based linux systems you may install (all) by issuing::
$ sudo apt-get install gfortran g++ gcc
See `setup.py <setup.py>`_ for optional (Python) dependencies.
Citing
------
The algortihm is from the following paper:
http://dx.doi.org/10.1090/S0025-5718-1988-0935077-0
::
@article{fornberg_generation_1988,
title={Generation of finite difference formulas on arbitrarily spaced grids},
author={Fornberg, Bengt},
journal={Mathematics of computation},
volume={51},
number={184},
pages={699--706},
year={1988}
doi={10.1090/S0025-5718-1988-0935077-0}
}
You may want to, in addition to the paper, cite finitediff (for e.g. reproducibility),
and you can get per-version DOIs from the zenodo archive:
.. image:: https://zenodo.org/badge/14988640.svg
:target: https://zenodo.org/badge/latestdoi/14988640
:alt: Zenodo DOI
Licensing
---------
The source code is Open Source and is released under the very permissive
`"simplified (2-clause) BSD license" <https://opensource.org/licenses/BSD-2-Clause>`_.
See `LICENSE <LICENSE>`_ for further details.
Author
------
Björn Ingvar Dahlgren (gmail address: bjodah). See file `AUTHORS <AUTHORS>`_ in root for a list of all authors.