runmat-runtime 0.4.1

Core runtime for RunMat with builtins, BLAS/LAPACK integration, and execution APIs
Documentation
{
  "title": "fftshift",
  "category": "math/fft",
  "keywords": [
    "fftshift",
    "fourier transform",
    "frequency centering",
    "spectrum",
    "gpu"
  ],
  "summary": "Shift zero-frequency components to the center of a spectrum.",
  "references": [],
  "gpu_support": {
    "elementwise": false,
    "reduction": false,
    "precisions": [
      "f32",
      "f64"
    ],
    "broadcasting": "none",
    "notes": "Uses the provider circshift hook when available; otherwise gathers once, shifts on the host, and re-uploads."
  },
  "fusion": {
    "elementwise": false,
    "reduction": false,
    "max_inputs": 1,
    "constants": "inline"
  },
  "requires_feature": null,
  "tested": {
    "unit": "builtins::math::fft::fftshift::tests",
    "integration": "builtins::math::fft::fftshift::tests::fftshift_gpu_roundtrip"
  },
  "description": "`fftshift(X)` circularly shifts the output of an FFT so that the zero-frequency component moves to the center of each transformed dimension. This makes spectra easier to inspect and aligns with MATLAB's plotting conventions.",
  "behaviors": [
    "When called without a dimension list, `fftshift` shifts along every dimension by `floor(size(X, dim) / 2)`.",
    "`fftshift(X, dims)` shifts only the specified dimensions. `dims` can be a scalar, vector, or logical mask.",
    "Dimensions of length 0 or 1 are left unchanged.",
    "Inputs can be real or complex and may already reside on the GPU (`gpuArray`)."
  ],
  "examples": [
    {
      "description": "Centering the spectrum of a 1-D FFT result with even length",
      "input": "x = [0 1 2 3 4 5 6 7];\nfx = fft(x);\ny = fftshift(fx)",
      "output": "y = [-4 -4-1.6569i -4-4i -4-9.6569i 28 -4+9.6569i -4+4i -4+1.6569i]"
    },
    {
      "description": "Handling odd-length vectors",
      "input": "x = 1:5;\ny = fftshift(x)",
      "output": "y = [4 5 1 2 3]"
    },
    {
      "description": "Centering both axes of a 2-D FFT",
      "input": "A = [1 2 3; 4 5 6];\nC = fftshift(A)",
      "output": "C =\n     6     4     5\n     3     1     2"
    },
    {
      "description": "Shifting only one dimension of a matrix",
      "input": "A = [1 2 3; 4 5 6];\nrowCentered = fftshift(A, 1)   % shift rows only",
      "output": "rowCentered =\n     4     5     6\n     1     2     3"
    },
    {
      "description": "Applying `fftshift` to a gpuArray spectrum",
      "input": "G = gpuArray(0:7);\ncentered = fftshift(G);\nH = gather(centered)",
      "output": "H = [4 5 6 7 0 1 2 3]"
    }
  ],
  "faqs": [
    {
      "question": "When should I call `fftshift`?",
      "answer": "Call `fftshift` whenever you need to center FFT outputs before visualising spectra, computing radial averages, or applying filters that expect zero frequency in the middle of the array."
    },
    {
      "question": "Does `fftshift` modify the phase or magnitude of the FFT?",
      "answer": "No. `fftshift` only reorders the samples. Magnitudes, phases, and the overall information content remain unchanged."
    },
    {
      "question": "How do I undo `fftshift`?",
      "answer": "Use `ifftshift`, which performs the inverse rearrangement. The sequence `ifftshift(fftshift(X))` returns `X` for all supported inputs."
    },
    {
      "question": "Can I apply `fftshift` to only one dimension?",
      "answer": "Yes. Pass a dimension index or vector, e.g. `fftshift(X, 2)` to shift column channels only."
    },
    {
      "question": "Does `fftshift` work with gpuArray inputs?",
      "answer": "Yes. RunMat keeps data on the GPU whenever the provider exposes the `circshift` hook, matching MATLAB's `gpuArray` behaviour."
    },
    {
      "question": "How does `fftshift` handle empty inputs?",
      "answer": "Empty arrays are returned unchanged with identical shape metadata."
    },
    {
      "question": "Can I use `fftshift` on logical arrays?",
      "answer": "Yes. Logical arrays are shifted without changing their logical element type."
    }
  ],
  "links": [
    {
      "label": "fft",
      "url": "./fft"
    },
    {
      "label": "ifft",
      "url": "./ifft"
    },
    {
      "label": "ifftshift",
      "url": "./ifftshift"
    },
    {
      "label": "circshift",
      "url": "./circshift"
    },
    {
      "label": "gpuArray",
      "url": "./gpuarray"
    },
    {
      "label": "gather",
      "url": "./gather"
    },
    {
      "label": "fft2",
      "url": "./fft2"
    },
    {
      "label": "ifft2",
      "url": "./ifft2"
    }
  ],
  "source": {
    "label": "`crates/runmat-runtime/src/builtins/math/fft/fftshift.rs`",
    "url": "https://github.com/runmat-org/runmat/blob/main/crates/runmat-runtime/src/builtins/math/fft/fftshift.rs"
  },
  "gpu_residency": "RunMat's auto-offload keeps FFT spectra on the GPU whenever the active provider exposes the `circshift` hook. In that case `fftshift` runs entirely on the device and downstream fused operations continue without a gather. If no GPU provider is registered—or it does not expose `circshift`—RunMat gathers the data once, performs the host shift, and uploads the result back to the device so subsequent work can still benefit from acceleration. You can always call `gpuArray` explicitly when you need MATLAB compatibility or want to guarantee a specific residency boundary.",
  "gpu_behavior": [
    "RunMat asks the active acceleration provider to execute `fftshift` via the `circshift` hook (with predetermined offsets). If the provider cannot satisfy the request, the tensor is gathered exactly once, shifted on the host, and optionally re-uploaded. Scalars remain on their existing device."
  ]
}