{"id":13812846,"url":"https://github.com/mreineck/pocketfft","last_synced_at":"2025-04-05T17:04:33.618Z","repository":{"id":37402501,"uuid":"357462016","full_name":"mreineck/pocketfft","owner":"mreineck","description":"Fork of https://gitlab.mpcdf.mpg.de/mtr/pocketfft to simplify external contributions","archived":false,"fork":false,"pushed_at":"2024-11-30T12:07:59.000Z","size":354,"stargazers_count":83,"open_issues_count":5,"forks_count":35,"subscribers_count":3,"default_branch":"cpp","last_synced_at":"2025-03-29T16:06:28.855Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mreineck.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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":"2021-04-13T07:27:14.000Z","updated_at":"2025-03-26T08:46:41.000Z","dependencies_parsed_at":"2023-01-19T11:09:28.545Z","dependency_job_id":"8c95d874-8ecc-4536-aa9a-af194ae8c987","html_url":"https://github.com/mreineck/pocketfft","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mreineck%2Fpocketfft","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mreineck%2Fpocketfft/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mreineck%2Fpocketfft/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mreineck%2Fpocketfft/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mreineck","download_url":"https://codeload.github.com/mreineck/pocketfft/tar.gz/refs/heads/cpp","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247369953,"owners_count":20927928,"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":[],"created_at":"2024-08-04T04:00:56.345Z","updated_at":"2025-04-05T17:04:33.594Z","avatar_url":"https://github.com/mreineck.png","language":"C++","funding_links":[],"categories":["DSP","Data processing"],"sub_categories":["DSP and Filtering"],"readme":"PocketFFT for C++\n=================\n\nThis is a heavily modified implementation of FFTPack [1,2], with the following\nadvantages:\n\n- Strictly C++11 compliant\n- More accurate twiddle factor computation\n- Worst case complexity for transform sizes with large prime factors is\n  `N*log(N)`, because Bluestein's algorithm [3] is used for these cases.\n- Supports multidimensional arrays and selection of the axes to be transformed.\n- Supports `float`, `double`, and `long double` types.\n- Supports fully complex and half-complex (i.e. complex-to-real and\n  real-to-complex) FFTs. For half-complex transforms, several conventions for\n  representing the complex-valued side are supported (reduced-size complex\n  array, FFTPACK-style half-complex format and Hartley transform).\n- Supports discrete cosine and sine transforms (Types I-IV)\n- Makes use of CPU vector instructions when performing 2D and higher-dimensional\n  transforms, if they are available.\n- Has a small internal cache for transform plans, which speeds up repeated\n  transforms of the same length (most significant for 1D transforms).\n- Has optional multi-threading support for multidimensional transforms\n\n\nLicense\n-------\n\n3-clause BSD (see LICENSE.md)\n\n\nSome code details\n-----------------\n\nTwiddle factor computation:\n\n- making use of symmetries to reduce number of sin/cos evaluations\n- all angles are reduced to the range `[0; pi/4]` for higher accuracy\n- if `n` sin/cos pairs are required, the trigonometric functions are only called\n  `2*sqrt(n)` times; the remaining values are obtained by evaluating the\n  angle addition theorems in a numerically accurate way.\n\nEfficient codelets are available for the factors:\n\n- 2, 3, 4, 5, 7, 8, 11 for complex-valued FFTs\n- 2, 3, 4, 5 for real-valued FFTs\n\nLarger prime factors are handled by somewhat less efficient, generic routines.\n\nFor lengths with very large prime factors, Bluestein's algorithm is used, and\ninstead of an FFT of length `n`, a convolution of length `n2 \u003e= 2*n-1`\nis performed, where `n2` is chosen to be highly composite.\n\n\n[1] Swarztrauber, P. 1982, Vectorizing the Fast Fourier Transforms\n    (New York: Academic Press), 51\n\n[2] https://www.netlib.org/fftpack/\n\n[3] https://en.wikipedia.org/wiki/Chirp_Z-transform\n\n\nConfiguration options\n=====================\n\nSince this is a header-only library, it can only be configured via preprocessor\nmacros.\n\nPOCKETFFT_CACHE_SIZE:\\\nif 0, disable all caching of FFT plans, else use an LRU cache with the\nrequested size. If undefined, assume a cache size of 0.\\\nNOTE: caching is disabled by default because its benefits are only really\nnoticeable for short 1D transforms. When using caching with transforms that\nhave very large axis lengths, it may use up a lot of memory, so only switch this\non if you know you really need it!\nDefault: undefined\n\nPOCKETFFT_NO_VECTORS:\\\nif defined, disable all support for CPU vector instructions.\\\nDefault: undefined\n\nPOCKETFFT_NO_MULTITHREADING:\\\nif defined, multi-threading will be disabled.\\\nDefault: undefined\n\n\nProgramming interface\n=====================\n\nAll symbols are encapsulated in the namespace `pocketfft`.\n\nArguments\n---------\n - `shape[_*]` contains the number of array entries along each axis.\n   For `c2c` and `r2r` transforms, `shape` is identical for input and output\n   arrays. For `r2c` transforms the shape of the input array must be specified,\n   while for `c2r` transforms the shape of the *output* array must be given.\n\n - `stride_*` describes array strides, i.e. the memory distance (in bytes)\n   between two neighboring array entries along an axis.\n\n - `axes` is a vector of nonnegative integers, describing the axes along\n   which a transform is to be carried out. The order of axes usually does not\n   matter, except for `r2c` and `c2r` transforms, where the last entry of\n   `axes` is treated specially.\n\n - `forward` describes the direction of a transform. Generally a forward\n   transform has a minus sign in the complex exponent, while the backward\n   transform has a positive one. Instead if `true`/`false`, the symbolic\n   constants `FORWARD`/`BACKWARD` can be used.\n   NOTE: Unlike many other libraries, pocketfft also allows a `forward` argument\n   in `r2c` and `c2r` transforms, instead of having hard-wired forward `r2c` and\n   backward `c2r` transforms. Calling `r2c` with `forward=false`, for\n   example, performs a transform from purely real data in the frequency domain\n   to Hermitian data in the position domain.\n   If you want the \"traditional\" behavior, call `r2c` with `forward=true` and\n   `c2r` with `forward=false`.\n\n - `fct` is a floating-point value which is used to scale the result of a\n   transform. `pocketfft`'s transforms are not normalized, so if normalization\n   is required, an appropriate scaling factor has to be specified.\n\n - `data_in` and `data_out` are pointers to the first element of the input\n   and output data arrays.\n\n - `nthreads` is a nonnegative integer specifying the number of threads to use\n   for the operation. A value of 0 means that the number of logical CPU cores\n   will be used.\n   This value is only a recommendation. If `pocketfft` is compiled without\n   multi-threading support, it will be silently ignored. For one-dimensional\n   transforms, multi-threading is disabled as well.\n\nGeneral constraints on arguments\n--------------------------------\n - `shape[_*]`, `stride_in` and `stride_out` must have the same `size()`\n   and must not be empty.\n - Entries in `shape[_*]` must be \u003e=1.\n - If `data_in==data_out`, `stride_in` and `stride_out` must have identical\n   content. These in-place transforms are fine for `c2c` and `r2r`, but not for\n   `r2c/c2r`.\n - Axes are numbered from 0 to `shape.size()-1`, inclusively.\n - Strides are measured in bytes, to allow maximum flexibility. Negative strides\n   are fine. Strides that lead to multiple accesses of the same memory address\n   are not allowed.\n - All memory addresses resulting from a combination of data pointers and\n   strides must have sufficient alignment. On x86 CPUs, badly aligned adresses\n   will only lead to slower execution, but on some other hardware, misaligned\n   memory accesses will cause a crash.\n - The same axis must not be specified more than once in an `axes` argument.\n - For `r2c` and `c2r` transforms: the length of the complex array along `axis`\n   (or the last entry in `axes`) is assumed to be `s/2 + 1`, where `s` is the\n   length of the corresponding axis of the real array.\n\nDetailed public interface\n-------------------------\n\n```\nusing shape_t = std::vector\u003cstd::size_t\u003e;\nusing stride_t = std::vector\u003cstd::ptrdiff_t\u003e;\n\nconstexpr bool FORWARD  = true,\n               BACKWARD = false;\n\ntemplate\u003ctypename T\u003e void c2c(const shape_t \u0026shape, const stride_t \u0026stride_in,\n  const stride_t \u0026stride_out, const shape_t \u0026axes, bool forward,\n  const complex\u003cT\u003e *data_in, complex\u003cT\u003e *data_out, T fct,\n  size_t nthreads=1)\n\ntemplate\u003ctypename T\u003e void r2c(const shape_t \u0026shape_in,\n  const stride_t \u0026stride_in, const stride_t \u0026stride_out, size_t axis,\n  bool forward, const T *data_in, complex\u003cT\u003e *data_out, T fct,\n  size_t nthreads=1)\n\n/* This function first carries out an r2c transform along the last axis in axes,\n   storing the result in data_out. Then, an in-place c2c transform\n   is carried out in data_out along all other axes. */\ntemplate\u003ctypename T\u003e void r2c(const shape_t \u0026shape_in,\n  const stride_t \u0026stride_in, const stride_t \u0026stride_out, const shape_t \u0026axes,\n  bool forward, const T *data_in, complex\u003cT\u003e *data_out, T fct,\n  size_t nthreads=1)\n\ntemplate\u003ctypename T\u003e void c2r(const shape_t \u0026shape_out,\n  const stride_t \u0026stride_in, const stride_t \u0026stride_out, size_t axis,\n  bool forward, const complex\u003cT\u003e *data_in, T *data_out, T fct,\n  size_t nthreads=1)\n\n/* This function first carries out a c2c transform along all axes except the\n   last one, storing the result into a temporary array. Then, a c2r transform\n   is carried out along the last axis, storing the result in data_out. */\ntemplate\u003ctypename T\u003e void c2r(const shape_t \u0026shape_out,\n  const stride_t \u0026stride_in, const stride_t \u0026stride_out, const shape_t \u0026axes,\n  bool forward, const complex\u003cT\u003e *data_in, T *data_out, T fct,\n  size_t nthreads=1)\n\n/* This function carries out a FFTPACK-style real-to-halfcomplex or\n   halfcomplex-to-real transform (depending on the parameter `real2hermitian`)\n   on all specified axes in the given order.\n   NOTE: interpreting the result of this function can be complicated when\n   transforming more than one axis! */\ntemplate\u003ctypename T\u003e void r2r_fftpack(const shape_t \u0026shape,\n  const stride_t \u0026stride_in, const stride_t \u0026stride_out, const shape_t \u0026axes,\n  bool real2hermitian, bool forward, const T *data_in, T *data_out, T fct,\n  size_t nthreads=1)\n\n/* For every requested axis, this function carries out a forward Fourier\n   transform, and the real and imaginary parts of the result are added before\n   the next axis is processed.\n   This is analogous to FFTW's implementation of the Hartley transform. */\ntemplate\u003ctypename T\u003e void r2r_separable_hartley(const shape_t \u0026shape,\n  const stride_t \u0026stride_in, const stride_t \u0026stride_out, const shape_t \u0026axes,\n  const T *data_in, T *data_out, T fct, size_t nthreads=1);\n\n/* This function carries out a full Fourier transform over the requested axes,\n   and the sum of real and imaginary parts of the result is stored in the output\n   array. For a single transformed axis, this is identical to\n   `r2r_separable_hartley`, but when transforming multiple axes, the results\n   are different.\n\n   NOTE: This function allocates temporary working space with a size\n   comparable to the input array. */\ntemplate\u003ctypename T\u003e void r2r_genuine_hartley(const shape_t \u0026shape,\n  const stride_t \u0026stride_in, const stride_t \u0026stride_out, const shape_t \u0026axes,\n  const T *data_in, T *data_out, T fct, size_t nthreads=1);\n\n/* if ortho==true, the transform is made orthogonal by these additional steps\n   in every 1D sub-transform:\n   Type 1 : multiply first and last input value by sqrt(2)\n            divide first and last output value by sqrt(2)\n   Type 2 : divide first output value by sqrt(2)\n   Type 3 : multiply first input value by sqrt(2)\n   Type 4 : nothing */\ntemplate\u003ctypename T\u003e void dct(const shape_t \u0026shape,\n  const stride_t \u0026stride_in, const stride_t \u0026stride_out, const shape_t \u0026axes,\n  int type, const T *data_in, T *data_out, T fct, bool ortho,\n  size_t nthreads=1);\n\n/* if ortho==true, the transform is made orthogonal by these additional steps\n   in every 1D sub-transform:\n   Type 1 : nothing\n   Type 2 : divide last output value by sqrt(2)\n   Type 3 : multiply last input value by sqrt(2)\n   Type 4 : nothing */\ntemplate\u003ctypename T\u003e void dst(const shape_t \u0026shape,\n  const stride_t \u0026stride_in, const stride_t \u0026stride_out, const shape_t \u0026axes,\n  int type, const T *data_in, T *data_out, T fct, bool ortho,\n  size_t nthreads=1);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmreineck%2Fpocketfft","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmreineck%2Fpocketfft","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmreineck%2Fpocketfft/lists"}