Metadata-Version: 2.3
Name: fftarray
Version: 0.5.1
Summary: A library to manage and effiently implement all complexities around the complex Fast Fourier Transform.
Project-URL: Homepage, https://github.com/QSTheory/fftarray
Project-URL: Documentation, https://qstheory.github.io/fftarray/main
Project-URL: Repository, https://github.com/QSTheory/fftarray
Project-URL: Issues, https://github.com/QSTheory/fftarray/issues
Project-URL: Changelog, https://qstheory.github.io/fftarray/main/changelog.html
Author: Stefan Seckmeyer, Christian Struckmann, Gabriel Müller, Jan-Niclas Kirsten-Siemß
License-File: LICENSE
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: array-api-compat>=1.11.0
Requires-Dist: numpy>=2.0
Requires-Dist: typing-extensions>=4.1
Provides-Extra: build-pip-deps
Requires-Dist: pip; extra == 'build-pip-deps'
Provides-Extra: check
Requires-Dist: array-api-strict>=2.3.0; extra == 'check'
Requires-Dist: bokeh; extra == 'check'
Requires-Dist: hypothesis; extra == 'check'
Requires-Dist: ipykernel; extra == 'check'
Requires-Dist: ipython; extra == 'check'
Requires-Dist: jax>=0.4.33; extra == 'check'
Requires-Dist: matplotlib; extra == 'check'
Requires-Dist: mypy>=0.910; extra == 'check'
Requires-Dist: nbformat; extra == 'check'
Requires-Dist: nbqa; extra == 'check'
Requires-Dist: pytest; extra == 'check'
Requires-Dist: pytest-cov; extra == 'check'
Requires-Dist: pytest-markdown-docs; extra == 'check'
Requires-Dist: pytest-split; extra == 'check'
Requires-Dist: pytest-xdist[psutil]; extra == 'check'
Requires-Dist: ruff; extra == 'check'
Requires-Dist: scipy; extra == 'check'
Requires-Dist: torch; extra == 'check'
Requires-Dist: xarray; extra == 'check'
Requires-Dist: z3-solver; extra == 'check'
Provides-Extra: dashboards
Requires-Dist: bokeh; extra == 'dashboards'
Requires-Dist: ipykernel; extra == 'dashboards'
Requires-Dist: ipython; extra == 'dashboards'
Requires-Dist: matplotlib; extra == 'dashboards'
Requires-Dist: scipy; extra == 'dashboards'
Requires-Dist: z3-solver; extra == 'dashboards'
Provides-Extra: deploy
Requires-Dist: hatch; extra == 'deploy'
Requires-Dist: twine; extra == 'deploy'
Provides-Extra: dev
Requires-Dist: array-api-strict>=2.3.0; extra == 'dev'
Requires-Dist: bokeh; extra == 'dev'
Requires-Dist: hatch; extra == 'dev'
Requires-Dist: hypothesis; extra == 'dev'
Requires-Dist: ipykernel; extra == 'dev'
Requires-Dist: ipython; extra == 'dev'
Requires-Dist: jax>=0.4.33; extra == 'dev'
Requires-Dist: lxml-html-clean; extra == 'dev'
Requires-Dist: m2r2; extra == 'dev'
Requires-Dist: matplotlib; extra == 'dev'
Requires-Dist: mypy>=0.910; extra == 'dev'
Requires-Dist: myst-nb; extra == 'dev'
Requires-Dist: nbconvert>=7.16.5; extra == 'dev'
Requires-Dist: nbformat; extra == 'dev'
Requires-Dist: nbqa; extra == 'dev'
Requires-Dist: nbsphinx; extra == 'dev'
Requires-Dist: nbsphinx-link; extra == 'dev'
Requires-Dist: pytest; extra == 'dev'
Requires-Dist: pytest-cov; extra == 'dev'
Requires-Dist: pytest-markdown-docs; extra == 'dev'
Requires-Dist: pytest-split; extra == 'dev'
Requires-Dist: pytest-xdist[psutil]; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Requires-Dist: scipy; extra == 'dev'
Requires-Dist: sphinx-book-theme>=1.0.1; extra == 'dev'
Requires-Dist: sphinx-copybutton; extra == 'dev'
Requires-Dist: sphinx-design; extra == 'dev'
Requires-Dist: sphinx>=6.1; extra == 'dev'
Requires-Dist: torch; extra == 'dev'
Requires-Dist: twine; extra == 'dev'
Requires-Dist: xarray; extra == 'dev'
Requires-Dist: z3-solver; extra == 'dev'
Provides-Extra: dimsolver
Requires-Dist: z3-solver; extra == 'dimsolver'
Provides-Extra: doc
Requires-Dist: bokeh; extra == 'doc'
Requires-Dist: ipython; extra == 'doc'
Requires-Dist: jax>=0.4.33; extra == 'doc'
Requires-Dist: lxml-html-clean; extra == 'doc'
Requires-Dist: m2r2; extra == 'doc'
Requires-Dist: matplotlib; extra == 'doc'
Requires-Dist: myst-nb; extra == 'doc'
Requires-Dist: nbconvert>=7.16.5; extra == 'doc'
Requires-Dist: nbsphinx; extra == 'doc'
Requires-Dist: nbsphinx-link; extra == 'doc'
Requires-Dist: scipy; extra == 'doc'
Requires-Dist: sphinx-book-theme>=1.0.1; extra == 'doc'
Requires-Dist: sphinx-copybutton; extra == 'doc'
Requires-Dist: sphinx-design; extra == 'doc'
Requires-Dist: sphinx>=6.1; extra == 'doc'
Requires-Dist: z3-solver; extra == 'doc'
Provides-Extra: jax
Requires-Dist: jax>=0.4.33; extra == 'jax'
Provides-Extra: torch
Requires-Dist: torch; extra == 'torch'
Description-Content-Type: text/x-rst

FFTArray: A Python Library for the Implementation of Discretized Multi-Dimensional Fourier Transforms
=====================================================================================================

`Intro <#intro>`__ \| `Installation <#installation>`__

Intro
-----

FFTArray is a Python library that handles multidimensional arrays and
their representation in dual spaces (original and frequency domain) and
provides the following highlight features:

- **From formulas to code**: The user can directly map analytical
  equations involving Fourier transforms to code without mixing
  discretization details with physics. This enables rapid prototyping of
  diverse physical models and solver strategies.
- **Seamless multidimensionality**: Dimensions are broadcast by name
  which enables a uniform API to seamlessly transition from single- to
  multi-dimensional systems.
- **High performance**: Avoidable scale and phase factors in the Fourier
  transform are automatically skipped. Via the `Python Array API
  Standard <https://data-apis.org/array-api/latest/>`__, FFTArray
  supports many different array libraries to enable for example hardware
  acceleration via GPUs.

Below we give a quick introduction to the basic functionality of the
library. For a more thorough description of FFTArray, we recommend
reading the `publication <https://arxiv.org/abs/2508.03697>`__ and the
`documentation <https://qstheory.github.io/fftarray/main>`__.

Adding Coordinate Grids to the FFT
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The continuous Fourier transform is defined as:

.. math::


   \begin{aligned}
       \mathcal{F}&: \ G(f) = \int_{-\infty}^{\infty}dx \ g(x)\ e^{- 2 \pi i fx},\quad \forall\ f\in \mathbb R,\\
       \widehat{\mathcal{F}}&: \ g(x) = \int_{-\infty}^{\infty}df\ G(f)\ e^{2 \pi i fx},\quad \forall\ x \in \mathbb R.
   \end{aligned}

When discretizing it on a finite grid in position and frequency space,
one does not only get the Fast Fourier transform (FFT) but some
additional phase and scale factors:

.. math::


   \begin{aligned}
       x_n &:= x_\mathrm{min} + n  \Delta x, \quad n = 0, \ldots, N-1 ,\\
       \quad f_m &:= f_\mathrm{min} + m \Delta f, \quad m = 0, \ldots, N-1,
   \end{aligned}

.. math::


   \begin{aligned}
       \text{(gdFT)} \quad G_m
       &= \Delta x \ \sum_{n=0}^{N-1} g_n \ \exp \left({-2 \pi i \ \left( f_\mathrm{min} + m \Delta f \right) \left( x_\mathrm{min} + n \Delta x \right) }\right) \\
       &= \Delta x
           \ {\textcolor{green}{\exp \left({\textcolor{green}{-} 2\pi i \ x_\mathrm{min} \  m \Delta f}\right)}}
           \ {\textcolor{green}{\exp \left({\textcolor{green}{-} 2\pi i \ x_\mathrm{min} \ f_\mathrm{min}}\right)}}
           \ \ \textcolor{black}{\mathrm{fft}} \left(
               g_n \ {\textcolor{green}{\exp \left({\textcolor{green}{-} 2\pi i \ f_\mathrm{min} \ n \Delta x}\right)}}
           \right),
   \end{aligned}

.. math::


   \begin{aligned}
       \text{(gdIFT)} \quad g_n
       &= \Delta f \ \sum_{m=0}^{N-1} G_m \ \exp  \left({2 \pi i \ \left( f_\mathrm{min} + m \Delta f \right) \left( x_\mathrm{min} + n \Delta x \right) } \right) \\
       &= {\textcolor{green}{\exp \left({\textcolor{green}{+} 2\pi i \ f_\mathrm{min} \ n \Delta x}\right)}}
           \ \ \textcolor{black}{\mathrm{ifft}} \left(
               G_m \ {\textcolor{green}{\exp \left({\textcolor{green}{+} 2\pi i \ x_\mathrm{min} \  m \Delta f}\right)}}
               \ {\textcolor{green}{\exp \left({\textcolor{green}{+} 2\pi i \ x_\mathrm{min} \ f_\mathrm{min}}\right)}} / \Delta x
           \right).
   \end{aligned}

:math:`\mathrm{fft}` and :math:`\mathrm{ifft}` follow here the
definition of NumPy’s default behavior in its `Discrete Fourier
Transform <https://numpy.org/doc/stable/reference/routines.fft.html>`__
module.

Keeping track of these coordinate-dependent scale and phase factors is
tedious and error-prone. Additionally the sample spacing and number of
samples in position space define the sample spacing in frequency space
and vice versa via :math:`1 = N \Delta x \Delta f` which usually needs
to be ensured by hand.

FFTArray automatically takes care of these and provides an easy to use
general discretized Fourier transform by managing the coordinate grids
in multiple dimensions, ensuring those are always correct. Arrays with
sampled values are combined with the dimension metadata as well as in
which space the values currently are:

.. code:: python

   import fftarray as fa

   dim_x = fa.dim_from_constraints(name="x", n=1024, pos_middle=0., d_pos=0.01, freq_middle=0)
   dim_y = fa.dim_from_constraints(name="y", n=2048, pos_min=-5., pos_max=6., freq_middle=0)

   arr_x = fa.coords_from_dim(dim_x, "pos")
   arr_y = fa.coords_from_dim(dim_y, "pos")

   arr_gauss_2d = fa.exp(-(arr_x**2 + arr_y**2)/0.2)
   arr_gauss_2d_in_freq_space = arr_gauss_2d.into_space("freq")

For a quick getting started, see `First
steps <https://qstheory.github.io/fftarray/main/first_steps.html>`__.

Built for Implementing Spectral Fourier Solvers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Spectral Fourier solvers like the split-step method require many
consecutive (inverse) Fourier transforms. In these cases the additional
scale and phase factors can be optimized out. By only applying these
phase factors lazily, FFTArray handles this use case with minimal
performance impact while still providing the comfort of ensuring the
application of all required phase factors. For quantum mechanics,
especially for simulating matter waves, the `matterwave
package <https://github.com/QSTheory/matterwave>`__ provides a
collection of helpers built on top of FFTArray.

Installation
------------

The required dependencies of FFTArray are kept minimal to ensure
compatibility with different environments. For most use cases we
recommend installing the optional constraint solver for easy Dimension
definition with the ``dimsolver`` option:

.. code:: shell

   pip install fftarray[dimsolver]

Any array library besides NumPy like for example
`JAX <https://github.com/jax-ml/jax?tab=readme-ov-file#installation>`__
should be installed following their respective documentation. Since each
of them have different approaches on how to handle for example GPU
support on different operating systems we do not recommend installing
them via the optional dependency groups of FFTArray.

Citing FFTArray
---------------

To cite FFTArray:

::

   @misc{seckmeyer2025,
       title={FFTArray: A Python Library for the Implementation of Discretized Multi-Dimensional Fourier Transforms},
       author={Stefan J. Seckmeyer and Christian Struckmann and Gabriel Müller and Jan-Niclas Kirsten-Siemß and Naceur Gaaloul},
       year={2025},
       eprint={2508.03697},
       archivePrefix={arXiv},
       primaryClass={physics.comp-ph},
       url={https://arxiv.org/abs/2508.03697},
   }
