{"id":13812829,"url":"https://github.com/aimukhin/minfft","last_synced_at":"2025-05-14T22:31:10.232Z","repository":{"id":35754618,"uuid":"123702137","full_name":"aimukhin/minfft","owner":"aimukhin","description":"A small and fast Discrete Fourier Transform library","archived":false,"fork":false,"pushed_at":"2024-04-11T07:58:58.000Z","size":751,"stargazers_count":43,"open_issues_count":0,"forks_count":10,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-19T07:39:23.766Z","etag":null,"topics":["c","cooley-tukey","cosine","dct","dft","dst","fft","fortran","multi-dimensional","sine"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aimukhin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-03T15:02:35.000Z","updated_at":"2024-11-16T13:59:19.000Z","dependencies_parsed_at":"2024-06-24T01:01:37.401Z","dependency_job_id":"3f025219-08c1-4ce1-89f8-1d6d7f4e492d","html_url":"https://github.com/aimukhin/minfft","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aimukhin%2Fminfft","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aimukhin%2Fminfft/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aimukhin%2Fminfft/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aimukhin%2Fminfft/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aimukhin","download_url":"https://codeload.github.com/aimukhin/minfft/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254239515,"owners_count":22037720,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","cooley-tukey","cosine","dct","dft","dst","fft","fortran","multi-dimensional","sine"],"created_at":"2024-08-04T04:00:56.009Z","updated_at":"2025-05-14T22:31:05.214Z","avatar_url":"https://github.com/aimukhin.png","language":"C","funding_links":[],"categories":["Data processing"],"sub_categories":["DSP and Filtering"],"readme":"# minfft\nA minimalistic Fast Fourier Transform library.\n\nIt achieves high performance by simple means.\n\n## Overview\n\nThe library routines compute:\n\n* Forward and inverse complex DFT,\n* Forward and inverse DFT of real data,\n* Cosine and sine transforms of types 2, 3, 4\n\nof any dimensionality and power-of-two lengths.\n\nThe library provides C and Fortran interfaces.\n\n## Contents\n- [Interface](#interface)\n- [Data types](#data-types)\n- [Transforms](#transforms)\n  - [Complex DFT](#complex-dft)\n  - [Inverse complex DFT](#inverse-complex-dft)\n  - [Real DFT](#real-dft)\n  - [Inverse real DFT](#inverse-real-dft)\n  - [DCT-2](#dct-2)\n  - [DST-2](#dst-2)\n  - [DCT-3](#dct-3)\n  - [DST-3](#dst-3)\n  - [DCT-4](#dct-4)\n  - [DST-4](#dst-4)\n- [Freeing auxiliary data](#freeing-auxiliary-data)\n- [Memory requirements](#memory-requirements)\n- [Implementation details](#implementation-details)\n- [Performance](#performance)\n- [Standards](#standards)\n- [License](#license)\n\n## Interface\nAll transform routines take three arguments:\n\n* input data pointer `x`,\n* output data pointer `y`,\n* auxiliary data pointer `a`.\n\nThe transform routines are capable of both in-place and out-of-place\noperation. In the latter case the input is left intact.\n\nAuxiliary data contain chains of precomputed constants and temporary\nmemory buffers, required for a transform routine to do its job. Once\nprepared, the auxiliary data can be reused as many times as needed.\nAlso, the same auxiliary data fit for both forward and inverse\ntransforms of the same kind.\n\nThese examples in C and Fortran show how the library functions are used:\n\n```C\n\t#include \"minfft.h\"\n\tminfft_cmpl x[N],y[N]; // input and output buffers\n\tminfft_aux *a; // aux data\n\t// prepare aux data\n\ta=minfft_mkaux_dft_1d(N);\n\t// do transforms\n\tminfft_dft(x,y,a);\n\tminfft_invdft(y,x,a);\n\t// free aux data\n\tminfft_free_aux(a);\n```\n\n```Fortran\n\tuse minfft\n\tcomplex(minfft_cmpl),dimension(n) :: x,y ! input and output buffers\n\ttype(minfft_aux) :: a ! aux data\n\t! prepare aux data\n\ta=minfft_mkaux_dft_1d(n)\n\t! do transforms\n\tcall minfft_dft(x,y,a)\n\tcall minfft_invdft(y,x,a)\n\t! free aux data\n\tcall minfft_free_aux(a)\n```\n\n## Data types\nThe library defines its own types for real and complex numbers, and for\nauxiliary data:\n\nC             | Fortran\n--------------|-----------------------\n`minfft_real` | `real(minfft_real)`\n`minfft_cmpl` | `complex(minfft_cmpl)`\n`minfft_aux`  | `type(minfft_aux)`\n\nBy default, `minfft_real` is `double`. If C99 native complex is\navailable, then `minfft_cmpl` is `double complex`. Otherwise,\n`minfft_cmpl` is an array of two `minfft_real`s. It is\nbinary-compatible with other known complex number types, such as MSVC\n`_Dcomplex` or C++ `complex\u003cdouble\u003e`.\n\nTo build a single precision version, define the `MINFFT_SINGLE` macro.\n\n## Transforms\nBelow is a list of transforms with their definitions, auxiliary data\nmakers, and transform routines.\n\nFor convenience, we provide aux data makers for one-, two- and\nthree-dimensional transforms, along with a generic any-dimensional one.\nThe dimensions are passed to aux maker routines in the C order (most\nrapidly varying index is the last). So, when calling from Fortran,\narray dimensions must be passed in the reverse order:\n\n```Fortran\n\tcomplex(minfft_cmpl),dimension(n1,n2,n3) :: z\n\ta=minfft_mkaux_dft_3d(n3,n2,n1)\n```\n\nAuxiliary data makers return NULL if an error occured.\n\nOur definitions of transforms, and formats of input and output data, are\nfully compatible with FFTW.\n\n### Complex DFT\n$$ y_n=\\sum_{k=0}^{N-1}x_k\\exp(-\\frac{2\\pi i}{N}kn), ~ n=0,1,\\dots,N{-}1 $$\n```C\nminfft_aux* minfft_mkaux_dft_1d (int N);\nminfft_aux* minfft_mkaux_dft_2d (int N1, int N2);\nminfft_aux* minfft_mkaux_dft_3d (int N1, int N2, int N3);\nminfft_aux* minfft_mkaux_dft (int d, int *Ns);\nvoid minfft_dft (minfft_cmpl *x, minfft_cmpl *y, const minfft_aux *a);\n```\n\n### Inverse complex DFT\n$$ y_n=\\sum_{k=0}^{N-1}x_k\\exp(\\frac{2\\pi i}{N}kn), ~ n=0,1,\\dots,N{-}1 $$\n```C\nminfft_aux* minfft_mkaux_dft_1d (int N);\nminfft_aux* minfft_mkaux_dft_2d (int N1, int N2);\nminfft_aux* minfft_mkaux_dft_3d (int N1, int N2, int N3);\nminfft_aux* minfft_mkaux_dft (int d, int *Ns);\nvoid minfft_invdft (minfft_cmpl *x, minfft_cmpl *y, const minfft_aux *a);\n```\n\n### Real DFT\nThis transform returns mostly non-redundant part of the complex DFT of\nreal data.\n\nFor a real array $` N_1 \\times \\dots \\times N_{d-1} \\times N_d `$\nit produces a complex array $` N_1 \\times \\dots \\times N_{d-1} \\times (\\frac{N_d}{2}+1) `$.\n\nNote that output takes a little more space than input. For in-place\noperation, make sure the data buffer is big enough to contain output.\n\n```C\nminfft_aux* minfft_mkaux_realdft_1d (int N);\nminfft_aux* minfft_mkaux_realdft_2d (int N1, int N2);\nminfft_aux* minfft_mkaux_realdft_3d (int N1, int N2, int N3);\nminfft_aux* minfft_mkaux_realdft (int d, int *Ns);\nvoid minfft_realdft (minfft_real *x, minfft_cmpl *z, const minfft_aux *a);\n```\n\n### Inverse real DFT\nThis is the inversion of the real DFT.\n\nIt takes a complex array $` N_1 \\times \\dots \\times N_{d-1} \\times (\\frac{N_d}{2}+1) `$\nand returns a real array $` N_1 \\times \\dots \\times N_{d-1} \\times N_d `$.\n\n**NB:** Multidimensional inverse real DFT **does not** preserve input.\n\n```C\nminfft_aux* minfft_mkaux_realdft_1d (int N);\nminfft_aux* minfft_mkaux_realdft_2d (int N1, int N2);\nminfft_aux* minfft_mkaux_realdft_3d (int N1, int N2, int N3);\nminfft_aux* minfft_mkaux_realdft (int d, int *Ns);\nvoid minfft_invrealdft (minfft_cmpl *z, minfft_real *y, const minfft_aux *a);\n```\n\n### DCT-2\n$$ y_n=2\\sum_{k=0}^{N-1}x_k\\cos(\\frac{\\pi}{N}(k+\\frac{1}{2})n), ~ n=0,1,\\dots,N{-}1 $$\n```C\nminfft_aux* minfft_mkaux_t2t3_1d (int N);\nminfft_aux* minfft_mkaux_t2t3_2d (int N1, int N2);\nminfft_aux* minfft_mkaux_t2t3_3d (int N1, int N2, int N3);\nminfft_aux* minfft_mkaux_t2t3 (int d, int *Ns);\nvoid minfft_dct2 (minfft_real *x, minfft_real *y, const minfft_aux *a);\n```\n\n### DST-2\n$$ y_n=2\\sum_{k=0}^{N-1}x_k\\sin(\\frac{\\pi}{N}(k+\\frac{1}{2})(n+1)), ~ n=0,1,\\dots,N{-}1 $$\n```C\nminfft_aux* minfft_mkaux_t2t3_1d (int N);\nminfft_aux* minfft_mkaux_t2t3_2d (int N1, int N2);\nminfft_aux* minfft_mkaux_t2t3_3d (int N1, int N2, int N3);\nminfft_aux* minfft_mkaux_t2t3 (int d, int *Ns);\nvoid minfft_dst2 (minfft_real *x, minfft_real *y, const minfft_aux *a);\n```\n\n### DCT-3\n$$ y_n=x_0+2\\sum_{k=1}^{N-1}x_k\\cos(\\frac{\\pi}{N}k(n+\\frac{1}{2})), ~ n=0,1,\\dots,N{-}1 $$\n```C\nminfft_aux* minfft_mkaux_t2t3_1d (int N);\nminfft_aux* minfft_mkaux_t2t3_2d (int N1, int N2);\nminfft_aux* minfft_mkaux_t2t3_3d (int N1, int N2, int N3);\nminfft_aux* minfft_mkaux_t2t3 (int d, int *Ns);\nvoid minfft_dct3 (minfft_real *x, minfft_real *y, const minfft_aux *a);\n```\n\n### DST-3\n$$ y_n=2\\sum_{k=0}^{N-2}x_k\\sin(\\frac{\\pi}{N}(k+1)(n+\\frac{1}{2}))+(-1)^{n}x_{N-1}, ~ n=0,1,\\dots,N{-}1 $$\n```C\nminfft_aux* minfft_mkaux_t2t3_1d (int N);\nminfft_aux* minfft_mkaux_t2t3_2d (int N1, int N2);\nminfft_aux* minfft_mkaux_t2t3_3d (int N1, int N2, int N3);\nminfft_aux* minfft_mkaux_t2t3 (int d, int *Ns);\nvoid minfft_dst3 (minfft_real *x, minfft_real *y, const minfft_aux *a);\n```\n\n### DCT-4\n$$ y_n=2\\sum_{k=0}^{N-1}x_k\\cos(\\frac{\\pi}{N}(k+\\frac{1}{2})(n+\\frac{1}{2})), ~ n=0,1,\\dots,N{-}1 $$\n```C\nminfft_aux* minfft_mkaux_t4_1d (int N);\nminfft_aux* minfft_mkaux_t4_2d (int N1, int N2);\nminfft_aux* minfft_mkaux_t4_3d (int N1, int N2, int N3);\nminfft_aux* minfft_mkaux_t4 (int d, int *Ns);\nvoid minfft_dct4 (minfft_real *x, minfft_real *y, const minfft_aux *a);\n```\n\n### DST-4\n$$ y_n=2\\sum_{k=0}^{N-1}x_k\\sin(\\frac{\\pi}{N}(k+\\frac{1}{2})(n+\\frac{1}{2})), ~ n=0,1,\\dots,N{-}1 $$\n```C\nminfft_aux* minfft_mkaux_t4_1d (int N);\nminfft_aux* minfft_mkaux_t4_2d (int N1, int N2);\nminfft_aux* minfft_mkaux_t4_3d (int N1, int N2, int N3);\nminfft_aux* minfft_mkaux_t4 (int d, int *Ns);\nvoid minfft_dst4 (minfft_real *x, minfft_real *y, const minfft_aux *a);\n```\n\n## Freeing auxiliary data\nIf not needed anymore, the memory consumed by the auxiliary data can\nbe freed by the `minfft_free_aux()` routine:\n\n```C\nvoid minfft_free_aux (minfft_aux *a);\n```\n\n## Memory requirements\nOur library does not try to save memory, and allocates temporary buffers\nwherever it benefits performance.\n\nThe amounts of memory, allocated for the auxiliary data of the\none-dimensional transforms, are given below:\n\nTransform                                | Auxiliary data size\n-----------------------------------------|---------------------\nComplex DFT of length `N`                | `2N` complex numbers\nReal DFT of length `N`                   | `3.5N` real numbers\nType-2 or Type-3 transform of length `N` | `5.5N` real numbers\nType-4 transform of length `N`           | `6N` real numbers\n\nMulti-dimensional transforms use a temporary buffer of the same size as\nthe input data. This value is the dominant term in their auxiliary data\nsize.\n\n## Implementation details\nThe complex DFT is computed by a split-radix (2/4), decimation in\nfrequency, explicitly recursive fast Fourier transform. This method\nachieves a remarkable balance between performance and simplicity, and it\nbehaves particularly cache-friendly, since it refers mostly to adjacent\nmemory locations.\n\nThe real transforms are reduced eventually to a half-length complex\ntransform.\n\nFor each transform, we first implement its one-dimensional,\nout-of-place, input-preserving, sequential input, strided output\nroutine. This allows us to compute a multi-dimensional transform by\nrepeated application of its one-dimensional routine along each\ndimension.\n\n## Performance\nBelow are the plots of speed and accuracy of our library, compared\nwith the libraries of similar design — KissFFT and PocketFFT.\nPerformance of a highly optimized machine-specific version of the FFTW\nlibrary is also shown for reference.\n\n![](docs/speed.svg)\n\n![](docs/accuracy.svg)\n\n## Standards\nC89, Fortran 2003.\n\n## License\nMIT.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faimukhin%2Fminfft","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faimukhin%2Fminfft","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faimukhin%2Fminfft/lists"}