{
  "aliases": null,
  "backlinks": [
    {
      "field": "uses",
      "target": "S966EZX3ZT"
    }
  ],
  "body": "\n## Statement\n\nLet $p$ be a prime, let $\\omega = e^{-2\\pi i/p}$, and let $g$ be a [[primitive root modulo $p$|0F33KX9Q6F]].\nFor an integer $j$ write $g^{j}$ and $g^{-j}$ for the residues in $\\set{1, \\ldots, p-1}$ of these powers modulo $p$.\nLet $x \\in \\C^p$ and let $X$ be its [[discrete Fourier transform|TST0GH66A5]], $X_k = \\sum_{n=0}^{p-1} x_n \\omega^{nk}$.\nDefine sequences of period $p - 1$ by $a_m = x_{g^m}$ and $c_m = \\omega^{g^{-m}}$.\nThen $X_0 = \\sum_{n=0}^{p-1} x_n$, and for $0 \\le q \\le p-2$,\n$$X_{g^{-q}} = x_0 + \\sum_{m=0}^{p-2} a_m\\, c_{q-m}.$$\nSo a DFT of prime length $p$ reduces to a cyclic [[convolution|2Z29JN3VES]] of length $p - 1$ and $O(p)$ further additions.\n\n## Remarks\n\nSince $g$ generates the multiplicative group modulo $p$, the maps $m \\mapsto g^m$ and $q \\mapsto g^{-q}$ are bijections from $\\set{0, \\ldots, p-2}$ onto $\\set{1, \\ldots, p-1}$.\nFor $n = g^m$ and $k = g^{-q}$ one has $nk \\equiv g^{-(q-m)} \\pmod p$, and $\\omega^{nk}$ depends only on $nk$ modulo $p$; this gives the formula.\nThe cyclic convolution of length $p-1$ can be computed by DFTs of length $p - 1$, which is composite for $p \u003e 3$.\nThese can use the [[Cooley–Tukey algorithm|9N8D9E5TB2]], possibly after zero padding to a power of $2$.\nExample: $p = 5$ and $g = 2$, so $(g^0, g^1, g^2, g^3) = (1, 2, 4, 3)$ and $(g^0, g^{-1}, g^{-2}, g^{-3}) = (1, 3, 4, 2)$.\nThe hypothesis that $p$ is prime gives a primitive root, and makes the nonzero indices a group under multiplication.\nFor composite lengths the nonzero indices do not form such a group.\n\n## Explanations\n\n### L1 human\n\nFast Fourier transforms usually split the length into factors, which fails when the length is prime.\nRader noticed that for a prime length the nonzero indices can be listed as powers of one number $g$.\nIn that order, the transform becomes a convolution, and convolutions can be done fast with other FFTs.\n\n### L2 human\n\nThe algorithm uses the structure of $(\\Z/p\\Z)^\\times$, which is cyclic of order $p - 1$.\nPermuting inputs by $n = g^m$ and outputs by $k = g^{-q}$ turns the $(p-1) \\times (p-1)$ block of the DFT matrix into a circulant matrix.\nCirculant matrices are diagonalised by the DFT, which is why the convolution can be done in $O(p \\log p)$ operations.\nWinograd's short-length FFT modules are built on the same reduction.\nBluestein's algorithm is an alternative that works for every length and does not need a primitive root.\n",
  "commit": "ff8a40749dc16545e3d2fc637f6b0196e81d0bfa",
  "front": {
    "about": [
      "TST0GH66A5"
    ],
    "kind": "statement",
    "msc": [
      "65T50",
      "11Y16"
    ],
    "name": "Rader's FFT algorithm",
    "role": "theorem",
    "same_as": {
      "wikidata": "Q7280126",
      "wikipedia": "Rader's FFT algorithm"
    },
    "sources": [
      {
        "url": "https://en.wikipedia.org/wiki/Rader's_FFT_algorithm"
      }
    ],
    "tag": "9HYM2ZMS31",
    "uses": [
      "TST0GH66A5",
      "0F33KX9Q6F",
      "2Z29JN3VES",
      "9N8D9E5TB2"
    ]
  },
  "kind": "statement",
  "link": "https://tamnd.github.io/math2/node/9HYM2ZMS31/",
  "links": [
    {
      "field": "about",
      "target": "TST0GH66A5"
    },
    {
      "field": "uses",
      "target": "TST0GH66A5"
    },
    {
      "field": "uses",
      "target": "0F33KX9Q6F"
    },
    {
      "field": "uses",
      "target": "2Z29JN3VES"
    },
    {
      "field": "uses",
      "target": "9N8D9E5TB2"
    }
  ],
  "markdown": "https://tamnd.github.io/math2/node/9HYM2ZMS31.md",
  "msc": [
    "65T50",
    "11Y16"
  ],
  "name": "Rader's FFT algorithm",
  "prov": null,
  "role": "theorem",
  "source": "https://github.com/tamnd/math2/blob/main/nodes/9HY/9HYM2ZMS31.md",
  "status": null,
  "tag": "9HYM2ZMS31",
  "uri": "m2://9HYM2ZMS31",
  "url": "https://tamnd.github.io/math2/wiki/raders-fft-algorithm/",
  "writing": {
    "tag": "9HYM2ZMS31",
    "kind": "statement",
    "level": "W0",
    "next": [
      {
        "what": "an inventory row",
        "note": "the row of the inventory that the node accounts for",
        "have": 0,
        "want": 1
      },
      {
        "what": "a source with a locator",
        "have": 0,
        "want": 1
      }
    ]
  }
}
