Module: Ignis::FFT::Operations

Defined in:
lib/nvruby/fft/operations.rb

Overview

FFT operations using cuFFT

Class Method Summary collapse

Class Method Details

.fft(x, axis: -1,, norm: :backward, stream: nil) ⇒ NvArray

1D Forward FFT

Parameters:

  • x (NvArray)

    Input array

  • axis (Integer) (defaults to: -1,)

    Axis along which to compute FFT (-1 for last)

  • norm (Symbol) (defaults to: :backward)

    Normalization mode (:forward, :backward, :ortho)

  • stream (CUDA::Stream, nil) (defaults to: nil)

    CUDA stream

Returns:



14
15
16
17
18
19
20
21
22
23
# File 'lib/nvruby/fft/operations.rb', line 14

def fft(x, axis: -1, norm: :backward, stream: nil)
  validate_input!(x)
  axis = normalize_axis(axis, x.ndim)

  n = x.shape[axis]
  output_dtype = DType.complex_dtype(x.dtype)

  result = execute_fft(x, output_dtype, :forward, [n], stream)
  apply_normalization(result, n, :forward, norm)
end

.fft2(x, axes: nil, norm: :backward, stream: nil) ⇒ NvArray

2D Forward FFT

Parameters:

  • x (NvArray)

    Input 2D array

  • axes (Array<Integer>, nil) (defaults to: nil)

    Axes for FFT (default last two)

  • norm (Symbol) (defaults to: :backward)

    Normalization mode

  • stream (CUDA::Stream, nil) (defaults to: nil)

    CUDA stream

Returns:

Raises:

  • (DimensionError)


47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/nvruby/fft/operations.rb', line 47

def fft2(x, axes: nil, norm: :backward, stream: nil)
  validate_input!(x)
  raise DimensionError, "Input must be at least 2D for fft2" if x.ndim < 2

  axes ||= [-2, -1]
  axes = axes.map { |a| normalize_axis(a, x.ndim) }

  n = axes.map { |a| x.shape[a] }
  output_dtype = DType.complex_dtype(x.dtype)

  result = execute_fft(x, output_dtype, :forward, n, stream)
  apply_normalization(result, n.reduce(:*), :forward, norm)
end

.fftn(x, axes: nil, norm: :backward, stream: nil) ⇒ NvArray

N-dimensional FFT

Parameters:

  • x (NvArray)

    Input array

  • axes (Array<Integer>, nil) (defaults to: nil)

    Axes for FFT

  • norm (Symbol) (defaults to: :backward)

    Normalization mode

  • stream (CUDA::Stream, nil) (defaults to: nil)

    CUDA stream

Returns:



86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/nvruby/fft/operations.rb', line 86

def fftn(x, axes: nil, norm: :backward, stream: nil)
  validate_input!(x)

  axes ||= (0...x.ndim).to_a
  axes = axes.map { |a| normalize_axis(a, x.ndim) }

  n = axes.map { |a| x.shape[a] }
  output_dtype = DType.complex_dtype(x.dtype)

  result = execute_fft(x, output_dtype, :forward, n, stream)
  apply_normalization(result, n.reduce(:*), :forward, norm)
end

.ifft(x, axis: -1,, norm: :backward, stream: nil) ⇒ NvArray

1D Inverse FFT

Parameters:

  • x (NvArray)

    Input complex array

  • axis (Integer) (defaults to: -1,)

    Axis along which to compute IFFT

  • norm (Symbol) (defaults to: :backward)

    Normalization mode (:forward, :backward, :ortho)

  • stream (CUDA::Stream, nil) (defaults to: nil)

    CUDA stream

Returns:



31
32
33
34
35
36
37
38
39
# File 'lib/nvruby/fft/operations.rb', line 31

def ifft(x, axis: -1, norm: :backward, stream: nil)
  validate_complex_input!(x)
  axis = normalize_axis(axis, x.ndim)

  n = x.shape[axis]

  result = execute_fft(x, x.dtype, :inverse, [n], stream)
  apply_normalization(result, n, :inverse, norm)
end

.ifft2(x, axes: nil, norm: :backward, stream: nil) ⇒ NvArray

2D Inverse FFT

Parameters:

  • x (NvArray)

    Input complex 2D array

  • axes (Array<Integer>, nil) (defaults to: nil)

    Axes for IFFT

  • norm (Symbol) (defaults to: :backward)

    Normalization mode

  • stream (CUDA::Stream, nil) (defaults to: nil)

    CUDA stream

Returns:

Raises:

  • (DimensionError)


67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/nvruby/fft/operations.rb', line 67

def ifft2(x, axes: nil, norm: :backward, stream: nil)
  validate_complex_input!(x)
  raise DimensionError, "Input must be at least 2D for ifft2" if x.ndim < 2

  axes ||= [-2, -1]
  axes = axes.map { |a| normalize_axis(a, x.ndim) }

  n = axes.map { |a| x.shape[a] }

  result = execute_fft(x, x.dtype, :inverse, n, stream)
  apply_normalization(result, n.reduce(:*), :inverse, norm)
end

.ifftn(x, axes: nil, norm: :backward, stream: nil) ⇒ NvArray

N-dimensional Inverse FFT

Parameters:

  • x (NvArray)

    Input complex array

  • axes (Array<Integer>, nil) (defaults to: nil)

    Axes for IFFT

  • norm (Symbol) (defaults to: :backward)

    Normalization mode

  • stream (CUDA::Stream, nil) (defaults to: nil)

    CUDA stream

Returns:



105
106
107
108
109
110
111
112
113
114
115
# File 'lib/nvruby/fft/operations.rb', line 105

def ifftn(x, axes: nil, norm: :backward, stream: nil)
  validate_complex_input!(x)

  axes ||= (0...x.ndim).to_a
  axes = axes.map { |a| normalize_axis(a, x.ndim) }

  n = axes.map { |a| x.shape[a] }

  result = execute_fft(x, x.dtype, :inverse, n, stream)
  apply_normalization(result, n.reduce(:*), :inverse, norm)
end

.irfft(x, n: nil, axis: -1,, norm: :backward, stream: nil) ⇒ NvArray

Complex-to-real Inverse FFT

Parameters:

  • x (NvArray)

    Complex input array (hermitian-symmetric)

  • n (Integer, nil) (defaults to: nil)

    Output length

  • axis (Integer) (defaults to: -1,)

    Axis for FFT

  • norm (Symbol) (defaults to: :backward)

    Normalization mode

  • stream (CUDA::Stream, nil) (defaults to: nil)

    CUDA stream

Returns:



146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/nvruby/fft/operations.rb', line 146

def irfft(x, n: nil, axis: -1, norm: :backward, stream: nil)
  validate_complex_input!(x)

  axis = normalize_axis(axis, x.ndim)
  input_size = x.shape[axis]
  n ||= (input_size - 1) * 2

  output_shape = x.shape.dup
  output_shape[axis] = n
  output_dtype = DType.real_dtype(x.dtype)

  result = execute_irfft(x, output_shape, output_dtype, n, stream)
  apply_normalization(result, n, :inverse, norm)
end

.rfft(x, n: nil, axis: -1,, norm: :backward, stream: nil) ⇒ NvArray

Real-to-complex FFT

Parameters:

  • x (NvArray)

    Real input array

  • n (Integer, nil) (defaults to: nil)

    FFT length (output length = n/2+1)

  • axis (Integer) (defaults to: -1,)

    Axis for FFT

  • norm (Symbol) (defaults to: :backward)

    Normalization mode

  • stream (CUDA::Stream, nil) (defaults to: nil)

    CUDA stream

Returns:

  • (NvArray)

    Complex output (hermitian-symmetric)

Raises:

  • (ArgumentError)


124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/nvruby/fft/operations.rb', line 124

def rfft(x, n: nil, axis: -1, norm: :backward, stream: nil)
  validate_input!(x)
  raise ArgumentError, "Input must be real for rfft" if DType.complex?(x.dtype)

  axis = normalize_axis(axis, x.ndim)
  n ||= x.shape[axis]

  output_shape = x.shape.dup
  output_shape[axis] = n / 2 + 1
  output_dtype = DType.complex_dtype(x.dtype)

  result = execute_rfft(x, output_shape, output_dtype, n, stream)
  apply_normalization(result, n, :forward, norm)
end