Skip to content

Module_SignalProcessing_Fourier

cyclone_dll edited this page Sep 13, 2026 · 12 revisions

Location: Home / Signal processing / Fourier transform

Signal Processing Module

Fourier Transform

The Vorcyc.Mathematics.SignalProcessing.Fourier namespace provides CPU-side Fourier transforms.

0.10.1 reorganization: The Fourier family has been consolidated under the Fourier/ source folder and the Vorcyc.Mathematics.SignalProcessing.Fourier namespace. Fft, Fft64, RealFft, RealFft64, and Stft were all relocated here from Transforms/; RealFft, RealFft64, and Stft also moved namespace from Vorcyc.Mathematics.SignalProcessing.Transforms to .Fourier (Fft and Fft64 were already in the Fourier namespace). The legacy RealOnlyFFT_Fp32 class has been removed; use RealFft (or Fft for full complex I/O) instead. A shared SoA radix-2 butterfly kernel — FftButterflyFp32 / FftButterflyFp64 — provides the SIMD and parallel execution paths used by Fft, Fft64, RealFft, and RealFft64.

The static FastFourierTransform class remains the high-level entry point for pointer / ComplexFp32-based transforms.

0.10.12: All FastFourierTransform.Forward / Inverse overloads (span, array, pointer, in-place — and therefore ITimeDomainSignal.TransformToFrequencyDomain) use the same SoA FftButterflyFp32 kernel as Fft / RealFft when SIMD or parallel is beneficial. Below the SIMD crossover they keep the original scalar FastFourierTransformNormal. The AoS FastFourierTransformSIMD / FastFourierTransformParallel kernels, the FftVersion enum, and FastFourierTransform.Version have been removed. Use ComputingContext / ComputingScope.

0.10.13: Stft.AveragePeriodogram averages complete windows only (SciPy/MATLAB welch); Operation.Welch accepts ComputingContext?; RealFft.PowerSpectrum gains context-aware overloads. 0.10.14: SciPy onesided Welch scaling (DC/Nyquist not ×2); RealFft/Fft spectrum APIs gain context overloads; STFT frame-parallel uses NestedFrameFftContext; WindowBuilder.OfType supports periodic windows. 0.10.15: FrequencyDomain.IndexToFrequency maps bins with TransformLength (FFT size), not ActualLength (unpadded samples). Zero-pad / Welch no longer yield bogus negative Hz on the upper half of a onesided spectrum. 0.10.18: Fft<T> / RealFft<T> dispatch float to Fft/RealFft and double to Fft64/RealFft64. Mode decomposition uses these facades so sample buffers stay in T.

0.9+: Use ComputingContext to specify FFT execution strategy (Forward(..., context), Direct(..., context), or ComputingScope).

GPU / CUDA: The main package does not include CUDA FFT (CudaFFT / ILGPU removed). See GPU policy. For native CPU FFT, see optional Extensions.FFTW.

All types below are in namespace: Vorcyc.Mathematics.SignalProcessing.Fourier


📒 Contents


Vorcyc.Mathematics.SignalProcessing.Fourier.FastFourierTransform class

Vorcyc.Mathematics.SignalProcessing.Fourier.FastFourierTransform is a static class for fast Fourier transform (FFT).

Methods

1. Forward

  • public static bool Forward(float* input, ComplexFp32* output, int N)

    • Performs forward FFT, converting real input to complex output.
    • Parameters:
      • input: Input data, real sequence (time domain).
      • output: Transform result, complex sequence.
      • N: FFT length.
    • Returns: Whether the operation succeeded.
  • public static bool Forward(float[] input, int offset, out ComplexFp32[] output, int N)

    • Performs forward FFT, converting real input to complex output.
    • Parameters:
      • input: Input data, real sequence (time domain).
      • offset: Offset into the input data.
      • output: Transform result, complex sequence.
      • N: FFT length.
    • Returns: Whether the operation succeeded.
  • public static bool Forward(ReadOnlySpan<float> input, Span<ComplexFp32> output)

    • Performs forward FFT, converting real input to complex output.
    • Parameters:
      • input: Input data, real sequence (time domain).
      • output: Transform result, complex sequence.
    • Returns: Whether the operation succeeded.
  • public static bool Forward(ComplexFp32* input, ComplexFp32* output, int N)

    • Performs forward FFT, converting complex input to complex output.
    • Parameters:
      • input: Input data, complex sequence (time domain).
      • output: Transform result, complex sequence.
      • N: FFT length.
    • Returns: Whether the operation succeeded.
  • public static bool Forward(ReadOnlySpan<ComplexFp32> input, Span<ComplexFp32> output)

    • Performs forward FFT, converting complex input to complex output.
    • Parameters:
      • input: Input data, complex sequence (time domain).
      • output: Transform result, complex sequence.
    • Returns: Whether the operation succeeded.
  • public static bool Forward(ComplexFp32[] input, int offset, ComplexFp32[] output, int N)

    • Performs forward FFT, converting complex input to complex output.
    • Parameters:
      • input: Input data, complex sequence (time domain).
      • offset: Offset into the input data.
      • output: Transform result, complex sequence.
      • N: FFT length.
    • Returns: Whether the operation succeeded.
  • public static bool Forward(ComplexFp32* data, int N)

    • Performs forward FFT, in-place version.
    • Parameters:
      • data: Input and output data, complex sequence.
      • N: FFT length.
    • Returns: Whether the operation succeeded.
  • public static bool Forward(ComplexFp32[] data, int offset, int N)

    • Performs forward FFT, in-place version.
    • Parameters:
      • data: Input and output data, complex sequence.
      • offset: Offset into the data.
      • N: FFT length.
    • Returns: Whether the operation succeeded.
  • public static bool Forward(Span<ComplexFp32> data)

    • Performs forward FFT, in-place version.
    • Parameters:
      • data: Input and output data, complex sequence.
    • Returns: Whether the operation succeeded.
  • public static bool Forward(float[] input, int offset, out ComplexFp32[] output, int N, ComputingContext? context)

    • Context-aware overload of Forward(float[], int, out ComplexFp32[], int). From 0.10.12 this selects the SoA FftButterflyFp32 SIMD / parallel kernel when beneficial, otherwise scalar FastFourierTransformNormal.
  • public static bool Forward(ReadOnlySpan<float> input, Span<ComplexFp32> output, ComputingContext? context)

    • Context-aware overload of Forward(ReadOnlySpan<float>, Span<ComplexFp32>).
  • public static bool Forward(ReadOnlySpan<ComplexFp32> input, Span<ComplexFp32> output, ComputingContext? context)

    • Context-aware overload of Forward(ReadOnlySpan<ComplexFp32>, Span<ComplexFp32>).

2. Inverse

  • public static bool Inverse(ComplexFp32* input, ComplexFp32* output, int N, bool scale = true)

    • Performs inverse FFT, converting complex input to complex output.
    • Parameters:
      • input: Input data, complex sequence (frequency domain).
      • output: Transform result, complex sequence (time domain).
      • N: Input length.
      • scale: Whether to scale; default is true.
    • Returns: Whether the operation succeeded.
  • public static bool Inverse(ComplexFp32[] input, int inOffset, out ComplexFp32[] output, int outOffset, int N, bool scale = true)

    • Performs inverse FFT, converting complex input to complex output.
    • Parameters:
      • input: Input data, complex sequence (frequency domain).
      • inOffset: Offset into the input data.
      • output: Transform result, complex sequence (time domain).
      • outOffset: Offset into the output data.
      • N: Input length.
      • scale: Whether to scale; default is true.
    • Returns: Whether the operation succeeded.
  • public static bool Inverse(ReadOnlySpan<ComplexFp32> input, Span<ComplexFp32> output, bool scale = true)

    • Performs inverse FFT, converting complex input to complex output.
    • Parameters:
      • input: Input data, complex sequence (frequency domain).
      • output: Transform result, complex sequence (time domain).
      • scale: Whether to scale; default is true.
    • Returns: Whether the operation succeeded.
  • public static bool Inverse(ComplexFp32* data, int N, bool scale = true)

    • Performs inverse FFT, in-place version.
    • Parameters:
      • data: Input and output data, complex sequence (frequency domain).
      • N: Input length.
      • scale: Whether to scale; default is true.
    • Returns: Whether the operation succeeded.
  • public static bool Inverse(ComplexFp32[] data, int offset, int N, bool scale = true)

    • Performs inverse FFT, in-place version.
    • Parameters:
      • data: Input and output data, complex sequence (frequency domain).
      • offset: Offset into the data.
      • N: Input length.
      • scale: Whether to scale; default is true.
    • Returns: Whether the operation succeeded.
  • public static bool Inverse(Span<ComplexFp32> data, bool scale = true)

    • Performs inverse FFT, in-place version.
    • Parameters:
      • data: Input and output data, complex sequence (frequency domain).
      • scale: Whether to scale; default is true.
    • Returns: Whether the operation succeeded.
  • public static bool Inverse(ComplexFp32[] input, int inOffset, out ComplexFp32[] output, int outOffset, int N, bool scale, ComputingContext? context)

    • Context-aware overload of the array Inverse(...). From 0.10.12 uses FftButterflyFp32 when beneficial (same policy as Forward).
  • public static bool Inverse(ReadOnlySpan<ComplexFp32> input, Span<ComplexFp32> output, bool scale, ComputingContext? context)

    • Context-aware overload of Inverse(ReadOnlySpan<ComplexFp32>, Span<ComplexFp32>, bool).
  • public static bool Inverse(Span<ComplexFp32> data, bool scale, ComputingContext? context)

    • Context-aware in-place overload of Inverse(Span<ComplexFp32>, bool).

Code example

The following example uses several methods of FastFourierTransform, with comments:

using System;
using Vorcyc.Mathematics.SignalProcessing.Fourier;

public class FastFourierTransformExample
{
    public static void Main()
    {
        // Define input signal
        float[] inputSignal = { 0.5f, 0.6f, 0.55f, 0.7f, 0.65f };

        // Perform forward FFT
        FastFourierTransform.Forward(inputSignal, 0, out var forwardOutput, inputSignal.Length);
        Console.WriteLine("Forward FFT Output:");
        foreach (var sample in forwardOutput)
        {
            Console.WriteLine($"Real: {sample.Real}, Imaginary: {sample.Imaginary}");
        }

        // Perform inverse FFT
        FastFourierTransform.Inverse(forwardOutput, 0, out var inverseOutput, 0, forwardOutput.Length);
        Console.WriteLine("Inverse FFT Output:");
        foreach (var sample in inverseOutput)
        {
            Console.WriteLine($"Real: {sample.Real}, Imaginary: {sample.Imaginary}");
        }
    }
}

Vorcyc.Mathematics.SignalProcessing.Fourier.Fft class

Vorcyc.Mathematics.SignalProcessing.Fourier.Fft is a complex in-place radix-2 FFT for float data. It implements IComplexTransform. The transform is computed in place on separate real / imaginary arrays (structure-of-arrays). ComputingContext-aware overloads dispatch to the shared SIMD / parallel butterfly kernel when the size is large enough to benefit; otherwise they run the scalar decimation-in-frequency butterfly.

Properties

1. Size

  • public int Size { get; }
    • Gets the FFT size.

Methods

1. Fft constructor

  • public Fft(int fftSize = 512)
    • Constructs an Fft for the given fftSize and precomputes the twiddle table. FFT size must be a power of two.
    • Parameters:
      • fftSize: FFT size.

2. Direct (in-place)

  • public void Direct(float[] re, float[] im)

  • public void Direct(Span<float> re, Span<float> im)

    • Forward FFT in place on the real / imaginary arrays.
    • Parameters:
      • re: Real parts (input and output).
      • im: Imaginary parts (input and output).
  • public void Direct(float[] re, float[] im, ComputingContext? context)

    • Context-aware forward FFT; selects scalar / SIMD / parallel according to context.
    • Parameters:
      • re: Real parts.
      • im: Imaginary parts.
      • context: Optional execution policy.

3. Direct (copy variant)

  • public void Direct(float[] inRe, float[] inIm, float[] outRe, float[] outIm)
  • public void Direct(ReadOnlySpan<float> inRe, ReadOnlySpan<float> inIm, Span<float> outRe, Span<float> outIm)
    • Forward FFT that copies the input to the output buffers before transforming in place.
    • Parameters:
      • inRe / inIm: Input real / imaginary parts.
      • outRe / outIm: Output real / imaginary parts.

4. DirectNorm

  • public void DirectNorm(float[] inRe, float[] inIm, float[] outRe, float[] outIm)
  • public void DirectNorm(ReadOnlySpan<float> inRe, ReadOnlySpan<float> inIm, Span<float> outRe, Span<float> outIm)
    • Normalized forward FFT (copy variant). Equivalent to Direct(...) for this class.

5. Inverse (in-place)

  • public void Inverse(float[] re, float[] im)
  • public void Inverse(Span<float> re, Span<float> im)
    • Inverse FFT in place.
  • public void Inverse(float[] re, float[] im, ComputingContext? context)
    • Context-aware inverse FFT.

6. Inverse (copy variant)

  • public void Inverse(float[] inRe, float[] inIm, float[] outRe, float[] outIm)
  • public void Inverse(ReadOnlySpan<float> inRe, ReadOnlySpan<float> inIm, Span<float> outRe, Span<float> outIm)
    • Inverse FFT that copies the input to the output buffers before transforming in place.

7. InverseNorm

  • public void InverseNorm(float[] re, float[] im)
  • public void InverseNorm(Span<float> re, Span<float> im)
    • Normalized inverse FFT in place (divides by Size).
  • public void InverseNorm(float[] re, float[] im, ComputingContext? context)
    • Context-aware normalized inverse FFT.
  • public void InverseNorm(float[] inRe, float[] inIm, float[] outRe, float[] outIm)
  • public void InverseNorm(ReadOnlySpan<float> inRe, ReadOnlySpan<float> inIm, Span<float> outRe, Span<float> outIm)
    • Normalized inverse FFT (copy variant).

8. MagnitudeSpectrum

  • public void MagnitudeSpectrum(float[] samples, float[] spectrum, bool normalize = false)
  • public void MagnitudeSpectrum(ReadOnlySpan<float> samples, float[] spectrum, bool normalize = false)
  • public void MagnitudeSpectrum(ReadOnlySpan<float> samples, Span<float> spectrum, bool normalize = false)
    • Computes spectrum = sqrt(re*re + im*im) from real samples. spectrum must have length at least Size/2 + 1.
  • public Signal MagnitudeSpectrum(Signal signal, bool normalize = false)
    • Computes and returns the magnitude spectrum as a Signal.

9. PowerSpectrum

  • public void PowerSpectrum(float[] samples, float[] spectrum, bool normalize = true)
  • public void PowerSpectrum(ReadOnlySpan<float> samples, float[] spectrum, bool normalize = true)
  • public void PowerSpectrum(ReadOnlySpan<float> samples, Span<float> spectrum, bool normalize = true)
    • Computes spectrum = re*re + im*im from real samples.
  • public float[] PowerSpectrum(Signal signal, bool normalize = true)
    • Computes and returns the power spectrum as a float[].

10. Shift (static)

  • public static void Shift(float[] samples)
  • public static void Shift(Span<float> samples)
    • In-place FFT shift (swaps the two halves). Throws ArgumentException if the length is odd.

Code example

using System;
using Vorcyc.Mathematics.SignalProcessing.Fourier;

public class FftExample
{
    public static void Main()
    {
        int fftSize = 8;
        var fft = new Fft(fftSize);

        float[] re = { 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f };
        float[] im = new float[fftSize];

        // Forward FFT in place
        fft.Direct(re, im);
        Console.WriteLine("Forward FFT:");
        for (int i = 0; i < fftSize; i++)
            Console.WriteLine($"re={re[i]}, im={im[i]}");

        // Inverse FFT in place (normalized)
        fft.InverseNorm(re, im);
        Console.WriteLine("Inverse (normalized):");
        for (int i = 0; i < fftSize; i++)
            Console.WriteLine($"re={re[i]}, im={im[i]}");
    }
}

Vorcyc.Mathematics.SignalProcessing.Fourier.Fft64 class

Vorcyc.Mathematics.SignalProcessing.Fourier.Fft64 is the double-precision counterpart of Fft: a complex in-place radix-2 FFT. ComputingContext-aware overloads dispatch to the FftButterflyFp64 SIMD / parallel kernel when beneficial.

Properties

1. Size

  • public int Size { get; }
    • Gets the FFT size.

Methods

1. Fft64 constructor

  • public Fft64(int fftSize = 512)
    • Constructs an Fft64 for the given fftSize. FFT size must be a power of two.
    • Parameters:
      • fftSize: FFT size.

2. Direct (in-place)

  • public void Direct(double[] re, double[] im)
  • public void Direct(Span<double> re, Span<double> im)
  • public void Direct(double[] re, double[] im, ComputingContext? context)
    • Forward FFT in place; the context-aware overload selects scalar / SIMD / parallel.

3. Direct (copy variant)

  • public void Direct(double[] inRe, double[] inIm, double[] outRe, double[] outIm)
  • public void Direct(ReadOnlySpan<double> inRe, ReadOnlySpan<double> inIm, Span<double> outRe, Span<double> outIm)
    • Forward FFT that copies the input to the output buffers before transforming in place.

4. DirectNorm

  • public void DirectNorm(double[] inRe, double[] inIm, double[] outRe, double[] outIm)
  • public void DirectNorm(ReadOnlySpan<double> inRe, ReadOnlySpan<double> inIm, Span<double> outRe, Span<double> outIm)
    • Normalized forward FFT (copy variant).

5. Inverse (in-place)

  • public void Inverse(double[] re, double[] im)
  • public void Inverse(Span<double> re, Span<double> im)
  • public void Inverse(double[] re, double[] im, ComputingContext? context)
    • Inverse FFT in place; the context-aware overload selects scalar / SIMD / parallel.

6. Inverse (copy variant)

  • public void Inverse(double[] inRe, double[] inIm, double[] outRe, double[] outIm)
  • public void Inverse(ReadOnlySpan<double> inRe, ReadOnlySpan<double> inIm, Span<double> outRe, Span<double> outIm)
    • Inverse FFT that copies the input to the output buffers before transforming in place.

7. InverseNorm

  • public void InverseNorm(double[] re, double[] im)
  • public void InverseNorm(Span<double> re, Span<double> im)
  • public void InverseNorm(double[] re, double[] im, ComputingContext? context)
  • public void InverseNorm(double[] inRe, double[] inIm, double[] outRe, double[] outIm)
  • public void InverseNorm(ReadOnlySpan<double> inRe, ReadOnlySpan<double> inIm, Span<double> outRe, Span<double> outIm)
    • Normalized inverse FFT (in-place, context-aware, and copy variants).

Code example

using System;
using Vorcyc.Mathematics.SignalProcessing.Fourier;

public class Fft64Example
{
    public static void Main()
    {
        int fftSize = 8;
        var fft = new Fft64(fftSize);

        double[] re = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 };
        double[] im = new double[fftSize];

        fft.Direct(re, im);
        Console.WriteLine("Forward FFT64:");
        for (int i = 0; i < fftSize; i++)
            Console.WriteLine($"re={re[i]}, im={im[i]}");

        fft.InverseNorm(re, im);
        Console.WriteLine("Inverse (normalized):");
        for (int i = 0; i < fftSize; i++)
            Console.WriteLine($"re={re[i]}, im={im[i]}");
    }
}

Vorcyc.Mathematics.SignalProcessing.Fourier.Fft<T> class

Fft<T> (0.10.18) is a generic complex-FFT facade: float dispatches to Fft, double to Fft64. Other T types throw NotSupportedException.

Methods

  • public Fft(int fftSize = 512)
  • public void Direct(T[] re, T[] im, ComputingContext? context = null)
  • public void Inverse(T[] re, T[] im, ComputingContext? context = null)
  • public void InverseNorm(T[] re, T[] im, ComputingContext? context = null)
var fft = new Fft<float>(256);
fft.Direct(re, im, ComputingContext.Simd);

Vorcyc.Mathematics.SignalProcessing.Fourier.RealFft<T> class

RealFft<T> (0.10.18) is the matching real-input facade: float → RealFft, double → RealFft64.

Methods

  • public RealFft(int size)
  • public void Direct(T[] input, T[] re, T[] im, ComputingContext? context = null)
  • public void Inverse(T[] re, T[] im, T[] output, ComputingContext? context = null)
  • public void InverseNorm(T[] re, T[] im, T[] output, ComputingContext? context = null)

Vorcyc.Mathematics.SignalProcessing.Fourier.RealFft class

Vorcyc.Mathematics.SignalProcessing.Fourier.RealFft is a complex FFT optimized for real-valued input (float). It implements IComplexTransform. It computes a half-size complex FFT internally and exposes direct / inverse / normalized-inverse transforms, magnitude and power spectra, and an FFT-shift utility. ComputingContext-aware overloads dispatch to the shared FftButterflyFp32 SIMD / parallel kernel for the inner half-size transform when beneficial. This replaces the removed RealOnlyFFT_Fp32.

Properties

1. Size

  • public int Size { get; }
    • Gets the FFT size (the configured real-input length).

Methods

1. RealFft constructor

  • public RealFft(int size)
    • Constructs a RealFft for the given size. FFT size must be a power of two.
    • Parameters:
      • size: FFT size.

2. Direct

  • public void Direct(float[] input, float[] re, float[] im)
  • public void Direct(float[] input, float[] re, float[] im, ComputingContext? context)
  • public void Direct(ReadOnlySpan<float> input, Span<float> re, Span<float> im, ComputingContext? context = null)
    • Forward FFT: real input -> complex (re, im). The context-aware overloads select scalar / SIMD / parallel for the inner half-size FFT.
  • public void Direct(float[] inRe, float[] inIm, float[] outRe, float[] outIm)
    • IComplexTransform signature; inIm is ignored.

3. DirectNorm

  • public void DirectNorm(float[] inRe, float[] inIm, float[] outRe, float[] outIm)
    • Normalized forward FFT (IComplexTransform signature; inIm is ignored). Equivalent to Direct(...) for this class.

4. Inverse

  • public void Inverse(float[] re, float[] im, float[] output)
  • public void Inverse(float[] re, float[] im, float[] output, ComputingContext? context)
  • public void Inverse(ReadOnlySpan<float> re, ReadOnlySpan<float> im, Span<float> output, ComputingContext? context = null)
    • Inverse FFT: complex (re, im) -> real output.
  • public void Inverse(float[] inRe, float[] inIm, float[] outRe, float[] outIm)
    • IComplexTransform signature; outIm is ignored.

5. InverseNorm

  • public void InverseNorm(float[] re, float[] im, float[] output)
  • public void InverseNorm(float[] re, float[] im, float[] output, ComputingContext? context)
  • public void InverseNorm(ReadOnlySpan<float> re, ReadOnlySpan<float> im, Span<float> output, ComputingContext? context = null)
    • Normalized inverse FFT: complex (re, im) -> real output (divided by the half-size).
  • public void InverseNorm(float[] inRe, float[] inIm, float[] outRe, float[] outIm)
    • IComplexTransform signature; outIm is ignored.

6. MagnitudeSpectrum

  • public void MagnitudeSpectrum(float[] samples, float[] spectrum, bool normalize = false)
  • public void MagnitudeSpectrum(ReadOnlySpan<float> samples, float[] spectrum, bool normalize = false)
  • public void MagnitudeSpectrum(ReadOnlySpan<float> samples, Span<float> spectrum, bool normalize = false)
    • Computes spectrum = sqrt(re*re + im*im). spectrum must have length at least Size/2 + 1.
  • public Signal MagnitudeSpectrum(Signal signal, bool normalize = false)
    • Returns the magnitude spectrum as a Signal.

7. PowerSpectrum

  • public void PowerSpectrum(float[] samples, float[] spectrum, bool normalize = true)
  • public void PowerSpectrum(ReadOnlySpan<float> samples, float[] spectrum, bool normalize = true)
  • public void PowerSpectrum(ReadOnlySpan<float> samples, Span<float> spectrum, bool normalize = true)
    • Computes spectrum = re*re + im*im.
  • public Signal PowerSpectrum(Signal signal, bool normalize = true)
    • Returns the power spectrum as a Signal.
  • public float[] PowerSpectrumArray(Signal signal, bool normalize = true)
    • Returns the power spectrum as a float[].

8. Shift (static)

  • public static void Shift(float[] samples)
  • public static void Shift(Span<float> samples)
    • In-place FFT shift (swaps the two halves). Throws ArgumentException if the length is odd.

Code example

using System;
using Vorcyc.Mathematics.SignalProcessing.Fourier;

public class RealFftExample
{
    public static void Main()
    {
        int fftSize = 8;
        var fft = new RealFft(fftSize);

        float[] input = { 0.5f, 0.6f, 0.55f, 0.7f, 0.65f, 0.8f, 0.75f, 0.9f };
        var re = new float[fftSize / 2 + 1];
        var im = new float[fftSize / 2 + 1];

        // Forward FFT: real input -> complex spectrum
        fft.Direct(input, re, im);
        Console.WriteLine("Forward FFT:");
        for (int i = 0; i < re.Length; i++)
            Console.WriteLine($"re={re[i]}, im={im[i]}");

        // Magnitude / power spectra
        var mag = new float[re.Length];
        var pow = new float[re.Length];
        fft.MagnitudeSpectrum(input, mag);
        fft.PowerSpectrum(input, pow);

        // Inverse FFT: complex spectrum -> real output
        var output = new float[fftSize];
        fft.InverseNorm(re, im, output);
        Console.WriteLine("Inverse (normalized):");
        foreach (var v in output) Console.WriteLine(v);
    }
}

Vorcyc.Mathematics.SignalProcessing.Fourier.RealFft64 class

Vorcyc.Mathematics.SignalProcessing.Fourier.RealFft64 is the double-precision counterpart of RealFft: a complex FFT optimized for real-valued input. ComputingContext-aware overloads dispatch to the FftButterflyFp64 SIMD / parallel kernel for the inner half-size transform when beneficial.

Properties

1. Size

  • public int Size { get; }
    • Gets the FFT size (the configured real-input length).

Methods

1. RealFft64 constructor

  • public RealFft64(int size)
    • Constructs a RealFft64 for the given size. FFT size must be a power of two.
    • Parameters:
      • size: FFT size.

2. Direct

  • public void Direct(double[] input, double[] re, double[] im)
  • public void Direct(double[] input, double[] re, double[] im, ComputingContext? context)
  • public void Direct(ReadOnlySpan<double> input, Span<double> re, Span<double> im, ComputingContext? context = null)
    • Forward FFT: real input -> complex (re, im).
  • public void Direct(double[] inRe, double[] inIm, double[] outRe, double[] outIm)
    • IComplexTransform-style signature; inIm is ignored.

3. DirectNorm

  • public void DirectNorm(double[] inRe, double[] inIm, double[] outRe, double[] outIm)
    • Normalized forward FFT (inIm is ignored). Equivalent to Direct(...) for this class.

4. Inverse

  • public void Inverse(double[] re, double[] im, double[] output)
  • public void Inverse(double[] re, double[] im, double[] output, ComputingContext? context)
  • public void Inverse(ReadOnlySpan<double> re, ReadOnlySpan<double> im, Span<double> output, ComputingContext? context = null)
    • Inverse FFT: complex (re, im) -> real output.
  • public void Inverse(double[] inRe, double[] inIm, double[] outRe, double[] outIm)
    • IComplexTransform-style signature; outIm is ignored.

5. InverseNorm

  • public void InverseNorm(double[] re, double[] im, double[] output)
  • public void InverseNorm(double[] re, double[] im, double[] output, ComputingContext? context)
  • public void InverseNorm(ReadOnlySpan<double> re, ReadOnlySpan<double> im, Span<double> output, ComputingContext? context = null)
    • Normalized inverse FFT: complex (re, im) -> real output.
  • public void InverseNorm(double[] inRe, double[] inIm, double[] outRe, double[] outIm)
    • IComplexTransform-style signature; outIm is ignored.

Code example

using System;
using Vorcyc.Mathematics.SignalProcessing.Fourier;

public class RealFft64Example
{
    public static void Main()
    {
        int fftSize = 8;
        var fft = new RealFft64(fftSize);

        double[] input = { 0.5, 0.6, 0.55, 0.7, 0.65, 0.8, 0.75, 0.9 };
        var re = new double[fftSize / 2 + 1];
        var im = new double[fftSize / 2 + 1];

        fft.Direct(input, re, im);

        var output = new double[fftSize];
        fft.InverseNorm(re, im, output);
        foreach (var v in output) Console.WriteLine(v);
    }
}

Vorcyc.Mathematics.SignalProcessing.Fourier.Stft class

Vorcyc.Mathematics.SignalProcessing.Fourier.Stft implements the Short-Time Fourier Transform and its inverse, plus spectrogram and magnitude-phase spectrogram helpers. It wraps a RealFft and a window function (WindowBuilder). All processing methods accept an optional ComputingContext that drives frame-level parallel dispatch when the workload is large enough; otherwise a serial path is used. Stft was moved here from Vorcyc.Mathematics.SignalProcessing.Transforms in 0.10.1.

Properties

1. Size

  • public int Size { get; }
    • Gets the FFT size used by the transformer.

Methods

1. Stft constructor

  • public Stft(int windowSize = 1024, int hopSize = 256, WindowType window = WindowType.Hann, int fftSize = 0)
    • Constructs an Stft transformer. When fftSize < windowSize, the FFT size is rounded up to the next power of two of windowSize.
    • Parameters:
      • windowSize: Size of the analysis window.
      • hopSize: Hop (overlap) size.
      • window: Type of the window function.
      • fftSize: Size of FFT; 0 auto-selects from windowSize.

2. Direct

  • public List<(float[], float[])> Direct(float[] input, ComputingContext? context = null)
  • public List<(float[], float[])> Direct(ReadOnlySpan<float> input, ComputingContext? context = null)
  • public List<(float[], float[])> Direct(Signal signal, ComputingContext? context = null)
    • Computes STFT and returns the list of per-frame spectra (re[], im[]).

3. Inverse

  • public float[] Inverse(List<(float[], float[])> stft, bool perfectReconstruction = true, ComputingContext? context = null)
    • Inverse STFT via overlap-add. When perfectReconstruction is true, hopSize must not exceed windowSize.

4. Spectrogram

  • public List<float[]> Spectrogram(float[] input, bool normalize = true, ComputingContext? context = null)
  • public List<float[]> Spectrogram(ReadOnlySpan<float> input, bool normalize = true, ComputingContext? context = null)
  • public List<float[]> Spectrogram(Signal signal, bool normalize = true, ComputingContext? context = null)
    • Computes the spectrogram as a list of per-frame power spectra.

5. AveragePeriodogram

  • public float[] AveragePeriodogram(float[] input, ComputingContext? context = null)
  • public float[] AveragePeriodogram(ReadOnlySpan<float> input, ComputingContext? context = null)
  • public float[] AveragePeriodogram(Signal signal, ComputingContext? context = null)
    • Computes a Welch-style averaged periodogram: mean of per-frame power spectra over complete windows only (trailing samples that do not fill a window are discarded — SciPy / MATLAB welch convention). Honors ComputingContext for frame-level parallel dispatch; when frames are parallelized, each frame FFT uses SIMD (not nested Parallel).

0.10.13: Dropped the previous trailing incomplete frame (and / (N+1) average). Breaking change for short signals / few frames.

6. MagnitudePhaseSpectrogram

  • public MagnitudePhaseList MagnitudePhaseSpectrogram(float[] input, ComputingContext? context = null)
  • public MagnitudePhaseList MagnitudePhaseSpectrogram(ReadOnlySpan<float> input, ComputingContext? context = null)
  • public MagnitudePhaseList MagnitudePhaseSpectrogram(Signal signal, ComputingContext? context = null)
    • Computes the spectrogram as separate lists of magnitudes and phases.

7. ReconstructMagnitudePhase

  • public float[] ReconstructMagnitudePhase(MagnitudePhaseList spectrogram, bool perfectReconstruction = true, ComputingContext? context = null)
    • Reconstructs samples from a magnitude/phase spectrogram via inverse STFT.

MagnitudePhaseList struct

  • public struct MagnitudePhaseList
    • public List<float[]> Magnitudes { get; set; } — list of per-frame magnitudes.
    • public List<float[]> Phases { get; set; } — list of per-frame phases.

Code example

using System;
using Vorcyc.Mathematics.SignalProcessing.Fourier;

public class StftExample
{
    public static void Main()
    {
        var stft = new Stft(windowSize: 1024, hopSize: 256);

        float[] signal = new float[16000];
        for (int i = 0; i < signal.Length; i++)
            signal[i] = MathF.Sin(2f * MathF.PI * 440f * i / 16000f);

        // Forward STFT
        var frames = stft.Direct(signal);
        Console.WriteLine($"Frames: {frames.Count}");

        // Spectrogram (list of power spectra)
        var spectrogram = stft.Spectrogram(signal);

        // Inverse STFT
        var reconstructed = stft.Inverse(frames);
        Console.WriteLine($"Reconstructed length: {reconstructed.Length}");
    }
}

FftButterflyFp32 / FftButterflyFp64 (internal kernels)

FftButterflyFp32 and FftButterflyFp64 are internal static structure-of-arrays radix-2 butterfly kernels shared by Fft / RealFft, Fft64 / RealFft64, and FastFourierTransform.Forward / Inverse. They are not part of the public API, but are documented here because they implement the SIMD and parallel execution paths selected by ComputingContext.

Each kernel exposes:

  • public static bool WillAccelerate(CpuExecutionMode mode, int size)
    • Returns true when the given mode and size would take an accelerated (SIMD or parallel) path. Below the SIMD crossover (~8K) the scalar caller-side butterfly is faster, so the kernels return false and the calling class falls back to its own scalar butterfly.
  • public static void Transform(float[]/double[] re, float[]/double[] im, int size, bool inverse, CpuExecutionMode mode, ComputingContext? context = null)
    • In-place radix-2 butterfly stages followed by the bit-reversal permutation. inverse selects the twiddle sign.

Three execution paths are selected via CpuExecutionMode: scalar (Normal), Vector<T> SIMD, and parallel. All paths produce results identical (up to floating-point rounding) to the original scalar decimation-in-frequency FFT.

Language / 语言: English · 简体中文


Home


首页

Clone this wiki locally