Module: Numo::Pocketfft

Defined in:
lib/numo/pocketfft/version.rb,
lib/numo/pocketfft.rb,
ext/numo/pocketfft/pocketfftext.c

Overview

Numo::Pocketfft is the module that has functions for Fourier transform.

Constant Summary collapse

VERSION =

The version of Numo::Pocketfft you are using.

'0.4.0'

Class Method Summary collapse

Class Method Details

.fft(a) ⇒ Numo::DComplex

Compute the 1-dimensional discrete Fourier Transform.

Parameters:

  • a (Numo::DFloat/Numo::DComplex)

    Real or complex 1-dimensional input array.

Returns:

  • (Numo::DComplex)

    Transformed data.

Raises:

  • (ArgumentError)

    This error is raised if input array is not Numo::NArray, is not one-dimensional array, or is empty.



15
16
17
18
19
20
21
# File 'lib/numo/pocketfft.rb', line 15

def fft(a)
  raise ArgumentError, 'Expect class of input array to be Numo::NArray.' unless a.is_a?(Numo::NArray)
  raise ArgumentError, 'Expect input array to be non-empty.' if a.empty?
  raise ArgumentError, 'Expect input array to be one-dimensional.' unless a.ndim == 1

  raw_fft(a, 0, inverse: false, real: false)
end

.fft2(a) ⇒ Numo::DComplex

Compute the 2-dimensional discrete Fourier Transform.

Parameters:

  • a (Numo::DFloat/Numo::DComplex)

    Real or complex 2-dimensional input array.

Returns:

  • (Numo::DComplex)

    Transformed data.

Raises:

  • (ArgumentError)

    This error is raised if input array is not Numo::NArray, is not two-dimensional array, or is empty.



39
40
41
42
43
44
45
# File 'lib/numo/pocketfft.rb', line 39

def fft2(a)
  raise ArgumentError, 'Expect class of input array to be Numo::NArray.' unless a.is_a?(Numo::NArray)
  raise ArgumentError, 'Expect input array to be non-empty.' if a.empty?
  raise ArgumentError, 'Expect input array to be two-dimensional.' unless a.ndim == 2

  fftn(a)
end

.fftconvolve(a, b) ⇒ Numo::DFloat/Numo::DComplex

Convolve two N-dimensinal arrays using dscrete Fourier Transform.

Examples:

require 'numo/pocketfftw'

a = Numo::DFloat[1, 2, 3]
b = Numo::DFloat[4, 5]
p Numo::Pocketfft.fftconvolve(a, b)
# Numo::DFloat#shape=[4]
# [4, 13, 22, 15]

a = Numo::DFloat[[1, 2], [3, 4]]
b = Numo::DFloat[[5, 6], [7, 8]]
p Numo::Pocketfft.fftconvolve(a, b)
# Numo::DFloat#shape=[3,3]
# [[5, 16, 12],
#  [22, 60, 40],
#  [21, 52, 32]]

Parameters:

  • a (Numo::DFloat/Numo::DComplex)

    Fisrt input array with any-dimension.

  • b (Numo::DFloat/Numo::DComplex)

    Second input array with the same number of dimensions as first input array.

Returns:

  • (Numo::DFloat/Numo::DComplex)

    The discrete linear convolution of ‘a’ with ‘b’.

Raises:

  • (ArgumentError)

    This error is raised if input arrays are not Numo::NArray, are not the same dimensionality, or are empty.



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/numo/pocketfft.rb', line 192

def fftconvolve(a, b)
  raise ArgumentError, 'Expect class of input array to be Numo::NArray.' unless a.is_a?(Numo::NArray) && b.is_a?(Numo::NArray)
  raise ArgumentError, 'Expect input array to be non-empty.' if a.empty? || b.empty?
  raise ArgumentError, 'Input arrays should have the same dimensionarity' if a.ndim != b.ndim

  ashp = a.shape
  bshp = b.shape

  return a * b if (ashp + bshp).all? { |el| el == 1 }

  retshp = Array.new(a.ndim) { |n| ashp[n] + bshp[n] - 1 }
  a_zp = Numo::DComplex.zeros(*retshp).tap { |arr| arr[*ashp.map { |n| 0...n }] = a }
  b_zp = Numo::DComplex.zeros(*retshp).tap { |arr| arr[*bshp.map { |n| 0...n }] = b }
  ret = ifftn(fftn(a_zp) * fftn(b_zp))

  return ret if a.is_a?(Numo::DComplex) || a.is_a?(Numo::SComplex) || b.is_a?(Numo::DComplex) || b.is_a?(Numo::SComplex)

  ret.real
end

.fftn(a) ⇒ Numo::DComplex

Compute the N-dimensional discrete Fourier Transform.

Parameters:

  • a (Numo::DFloat/Numo::DComplex)

    Real or complex input array with any-dimension.

Returns:

  • (Numo::DComplex)

    Transformed data.

Raises:

  • (ArgumentError)

    This error is raised if input array is not Numo::NArray or is empty.



63
64
65
66
67
68
69
70
71
72
73
# File 'lib/numo/pocketfft.rb', line 63

def fftn(a)
  raise ArgumentError, 'Expect class of input array to be Numo::NArray.' unless a.is_a?(Numo::NArray)
  raise ArgumentError, 'Expect input array to be non-empty.' if a.empty?

  return raw_fft(a, 0, inverse: false, real: false) if a.ndim == 1

  last_axis_id = a.ndim - 1
  b = raw_fft(a, last_axis_id, inverse: false, real: false)
  (last_axis_id - 1).downto(0) { |ax_id| b = raw_fft(b, ax_id, inverse: false, real: false) }
  b
end

.ifft(a) ⇒ Numo::DComplex

Compute the 1-dimensional inverse discrete Fourier Transform.

Parameters:

  • a (Numo::DComplex)

    Complex 1-dimensional input array.

Returns:

  • (Numo::DComplex)

    Inversed transformed data.

Raises:

  • (ArgumentError)

    This error is raised if input array is not Numo::NArray, is not one-dimensional array, or is empty.



27
28
29
30
31
32
33
# File 'lib/numo/pocketfft.rb', line 27

def ifft(a)
  raise ArgumentError, 'Expect class of input array to be Numo::NArray.' unless a.is_a?(Numo::NArray)
  raise ArgumentError, 'Expect input array to be non-empty.' if a.empty?
  raise ArgumentError, 'Expect input array to be one-dimensional.' unless a.ndim == 1

  raw_fft(a, 0, inverse: true, real: false)
end

.ifft2(a) ⇒ Numo::DComplex

Compute the 2-dimensional inverse discrete Fourier Transform.

Parameters:

  • a (Numo::DComplex)

    Complex 2-dimensional input array.

Returns:

  • (Numo::DComplex)

    Inversed transformed data.

Raises:

  • (ArgumentError)

    This error is raised if input array is not Numo::NArray, is not two-dimensional array, or is empty.



51
52
53
54
55
56
57
# File 'lib/numo/pocketfft.rb', line 51

def ifft2(a)
  raise ArgumentError, 'Expect class of input array to be Numo::NArray.' unless a.is_a?(Numo::NArray)
  raise ArgumentError, 'Expect input array to be non-empty.' if a.empty?
  raise ArgumentError, 'Expect input array to be two-dimensional.' unless a.ndim == 2

  ifftn(a)
end

.ifftn(a) ⇒ Numo::DComplex

Compute the N-dimensional inverse discrete Fourier Transform.

Parameters:

  • a (Numo::DComplex)

    Complex input array with any-dimension.

Returns:

  • (Numo::DComplex)

    Inversed transformed data.

Raises:

  • (ArgumentError)

    This error is raised if input array is not Numo::NArray or is empty.



79
80
81
82
83
84
85
86
87
88
89
# File 'lib/numo/pocketfft.rb', line 79

def ifftn(a)
  raise ArgumentError, 'Expect class of input array to be Numo::NArray.' unless a.is_a?(Numo::NArray)
  raise ArgumentError, 'Expect input array to be non-empty.' if a.empty?

  return raw_fft(a, 0, inverse: true, real: false) if a.ndim == 1

  last_axis_id = a.ndim - 1
  b = raw_fft(a, 0, inverse: true, real: false)
  1.upto(last_axis_id) { |ax_id| b = raw_fft(b, ax_id, inverse: true, real: false) }
  b
end

.irfft(a) ⇒ Numo::DFloat

Compute the inverse of the 1-dimensional discrete Fourier Transform of real input.

Parameters:

  • a (Numo::DComplex)

    Complex 1-dimensional input array.

Returns:

  • (Numo::DFloat)

    Inverse transformed data.

Raises:

  • (ArgumentError)

    This error is raised if input array is not Numo::NArray, is not one-dimensional array, or is empty.



107
108
109
110
111
112
113
# File 'lib/numo/pocketfft.rb', line 107

def irfft(a)
  raise ArgumentError, 'Expect class of input array to be Numo::NArray.' unless a.is_a?(Numo::NArray)
  raise ArgumentError, 'Expect input array to be non-empty.' if a.empty?
  raise ArgumentError, 'Expect input array to be one-dimensional.' unless a.ndim == 1

  raw_fft(a, 0, inverse: true, real: true)
end

.irfft2(a) ⇒ Numo::DFloat

Compute the inverse of the 2-dimensional discrete Fourier Transform of real input.

Parameters:

  • a (Numo::DComplex)

    Complex 2-dimensional input array.

Returns:

  • (Numo::DFloat)

    Inverse transformed data.

Raises:

  • (ArgumentError)

    This error is raised if input array is not Numo::NArray, is not two-dimensional array, or is empty.



131
132
133
134
135
136
137
# File 'lib/numo/pocketfft.rb', line 131

def irfft2(a)
  raise ArgumentError, 'Expect class of input array to be Numo::NArray.' unless a.is_a?(Numo::NArray)
  raise ArgumentError, 'Expect input array to be non-empty.' if a.empty?
  raise ArgumentError, 'Expect input array to be two-dimensional.' unless a.ndim == 2

  irfftn(a)
end

.irfftn(a) ⇒ Numo::DFloat

Compute the inverse of the N-dimensional discrete Fourier Transform of real input.

Parameters:

  • a (Numo::DComplex)

    Complex input array with any-dimension.

Returns:

  • (Numo::DFloat)

    Inverse transformed data.

Raises:

  • (ArgumentError)

    This error is raised if input array is not Numo::NArray or is empty.



159
160
161
162
163
164
165
166
167
168
169
# File 'lib/numo/pocketfft.rb', line 159

def irfftn(a)
  raise ArgumentError, 'Expect class of input array to be Numo::NArray.' unless a.is_a?(Numo::NArray)
  raise ArgumentError, 'Expect input array to be non-empty.' if a.empty?

  return raw_fft(a, 0, inverse: true, real: true) if a.ndim == 1

  last_axis_id = a.ndim - 1
  b = raw_fft(a, 0, inverse: true, real: false)
  1.upto(last_axis_id - 1) { |ax_id| b = raw_fft(b, ax_id, inverse: true, real: false) }
  raw_fft(b, last_axis_id, inverse: true, real: true)
end

.rfft(a) ⇒ Numo::DComplex

Compute the 1-dimensional discrete Fourier Transform for real input.

Parameters:

  • a (Numo::DFloat)

    Real 1-dimensional input array.

Returns:

  • (Numo::DComplex)

    Transformed data.

Raises:

  • (ArgumentError)

    This error is raised if input array is not Numo::NArray, is not one-dimensional array, or is empty.



95
96
97
98
99
100
101
# File 'lib/numo/pocketfft.rb', line 95

def rfft(a)
  raise ArgumentError, 'Expect class of input array to be Numo::NArray.' unless a.is_a?(Numo::NArray)
  raise ArgumentError, 'Expect input array to be non-empty.' if a.empty?
  raise ArgumentError, 'Expect input array to be one-dimensional.' unless a.ndim == 1

  raw_fft(a, 0, inverse: false, real: true)
end

.rfft2(a) ⇒ Numo::DComplex

Compute the 2-dimensional discrete Fourier Transform for real input.

Parameters:

  • a (Numo::DFloat)

    Real 2-dimensional input array.

Returns:

  • (Numo::DComplex)

    Transformed data.

Raises:

  • (ArgumentError)

    This error is raised if input array is not Numo::NArray, is not two-dimensional array, or is empty.



119
120
121
122
123
124
125
# File 'lib/numo/pocketfft.rb', line 119

def rfft2(a)
  raise ArgumentError, 'Expect class of input array to be Numo::NArray.' unless a.is_a?(Numo::NArray)
  raise ArgumentError, 'Expect input array to be non-empty.' if a.empty?
  raise ArgumentError, 'Expect input array to be two-dimensional.' unless a.ndim == 2

  rfftn(a)
end

.rfftn(a) ⇒ Numo::DComplex

Compute the N-dimensional discrete Fourier Transform for real input.

Parameters:

  • a (Numo::DFloat)

    Real input array with any-dimension.

Returns:

  • (Numo::DComplex)

    Transformed data.

Raises:

  • (ArgumentError)

    This error is raised if input array is not Numo::NArray or is empty.



143
144
145
146
147
148
149
150
151
152
153
# File 'lib/numo/pocketfft.rb', line 143

def rfftn(a)
  raise ArgumentError, 'Expect class of input array to be Numo::NArray.' unless a.is_a?(Numo::NArray)
  raise ArgumentError, 'Expect input array to be non-empty.' if a.empty?

  return raw_fft(a, 0, inverse: false, real: true) if a.ndim == 1

  last_axis_id = a.ndim - 1
  b = raw_fft(a, last_axis_id, inverse: false, real: true)
  (last_axis_id - 1).downto(0) { |ax_id| b = raw_fft(b, ax_id, inverse: false, real: false) }
  b
end