VTK  9.2.6
vtkFFT.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkFFT.h
5 
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10  This software is distributed WITHOUT ANY WARRANTY; without even
11  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  PURPOSE. See the above copyright notice for more information.
13 
14 =========================================================================*/
32 #ifndef vtkFFT_h
33 #define vtkFFT_h
34 
35 #include "vtkCommonMathModule.h" // For export macro
36 #include "vtkMath.h" // For vtkMath::Pi
37 #include "vtkObject.h"
38 
39 #include "vtk_kissfft.h" // For kiss_fft_scalar, kiss_fft_cpx
40 // clang-format off
41 #include VTK_KISSFFT_HEADER(kiss_fft.h)
42 #include VTK_KISSFFT_HEADER(tools/kiss_fftr.h)
43 // clang-format on
44 
45 #include <vector> // For std::vector
46 #include <cmath> // for std::sin, std::cos, std::sqrt
47 
48 class VTKCOMMONMATH_EXPORT vtkFFT : public vtkObject
49 {
50 public:
51  using ScalarNumber = kiss_fft_scalar;
52  using ComplexNumber = kiss_fft_cpx;
53 
54  static vtkFFT* New();
55  vtkTypeMacro(vtkFFT, vtkObject);
56  void PrintSelf(ostream& os, vtkIndent indent) override;
57 
59 
66  static std::vector<ComplexNumber> Fft(const std::vector<ComplexNumber>& in);
67  static std::vector<ComplexNumber> Fft(const std::vector<ScalarNumber>& in);
69 
76  static std::vector<ComplexNumber> RFft(const std::vector<ScalarNumber>& in);
77 
88  static std::vector<ComplexNumber> IFft(const std::vector<ComplexNumber>& in);
89 
98  static std::vector<ScalarNumber> IRFft(const std::vector<ComplexNumber>& in);
99 
103  static inline double Abs(const ComplexNumber& in);
104 
108  static inline double SquaredAbs(const ComplexNumber& in);
109 
113  static std::vector<double> FftFreq(int windowLength, double sampleSpacing);
114 
119  static std::vector<double> RFftFreq(int windowLength, double sampleSpacing);
120 
122 
131  using WindowGenerator = double (*)(const std::size_t, const std::size_t);
132 
133  static inline double HanningGenerator(const std::size_t x, const std::size_t size);
134  static inline double BartlettGenerator(const std::size_t x, const std::size_t size);
135  static inline double SineGenerator(const std::size_t x, const std::size_t size);
136  static inline double BlackmanGenerator(const std::size_t x, const std::size_t size);
137  static inline double RectangularGenerator(const std::size_t x, const std::size_t size);
139 
144  template <typename Array1D>
145  static void GenerateKernel1D(Array1D* kernel, const std::size_t n, WindowGenerator generator);
146 
151  template <typename Array2D>
152  static void GenerateKernel2D(
153  Array2D* kernel, const std::size_t n, const std::size_t m, WindowGenerator generator);
154 
155 protected:
156  vtkFFT() = default;
157  ~vtkFFT() override = default;
158 
159 private:
160  vtkFFT(const vtkFFT&) = delete;
161  void operator=(const vtkFFT&) = delete;
162 };
163 
164 //------------------------------------------------------------------------------
165 double vtkFFT::Abs(const ComplexNumber& in)
166 {
167  return std::sqrt(in.r * in.r + in.i * in.i);
168 }
169 
170 //------------------------------------------------------------------------------
172 {
173  return in.r * in.r + in.i * in.i;
174 }
175 
176 //------------------------------------------------------------------------------
177 double vtkFFT::HanningGenerator(const std::size_t x, const std::size_t size)
178 {
179  return 0.5 * (1.0 - std::cos(2.0 * vtkMath::Pi() * x / (size - 1)));
180 }
181 
182 //------------------------------------------------------------------------------
183 double vtkFFT::BartlettGenerator(const std::size_t x, const std::size_t size)
184 {
185  return 2.0 * x / (size - 1);
186 }
187 
188 //------------------------------------------------------------------------------
189 double vtkFFT::SineGenerator(const std::size_t x, const std::size_t size)
190 {
191  return std::sin(vtkMath::Pi() * x / size);
192 }
193 
194 //------------------------------------------------------------------------------
195 double vtkFFT::BlackmanGenerator(const std::size_t x, const std::size_t size)
196 {
197  return 0.42 - 0.5 * std::cos((2.0 * vtkMath::Pi() * x) / size) +
198  0.08 * std::cos((4.0 * vtkMath::Pi() * x) / size);
199 }
200 
201 //------------------------------------------------------------------------------
202 double vtkFFT::RectangularGenerator(const std::size_t, const std::size_t)
203 {
204  return 1.0;
205 }
206 
207 //------------------------------------------------------------------------------
208 template <typename Array1D>
209 void vtkFFT::GenerateKernel1D(Array1D* kernel, const std::size_t n, WindowGenerator generator)
210 {
211  const std::size_t half = (n / 2) + (n % 2);
212  for (std::size_t i = 0; i < half; ++i)
213  {
214  kernel[i] = kernel[n - 1 - i] = generator(i, n);
215  }
216 }
217 
218 //------------------------------------------------------------------------------
219 template <typename Array2D>
221  Array2D* kernel, const std::size_t n, const std::size_t m, WindowGenerator generator)
222 {
223  const std::size_t halfX = (n / 2) + (n % 2);
224  const std::size_t halfY = (m / 2) + (m % 2);
225  for (std::size_t i = 0; i < halfX; ++i)
226  {
227  for (std::size_t j = 0; j < halfY; ++j)
228  {
229  // clang-format off
230  kernel[i][j]
231  = kernel[n - 1 - i][j]
232  = kernel[i][m - 1 - j]
233  = kernel[n - 1 - i][m - 1 - j]
234  = generator(i, n) * generator(j, m);
235  // clang-format on
236  }
237  }
238 }
239 
240 #endif
static double RectangularGenerator(const std::size_t x, const std::size_t size)
Window generator functions.
Definition: vtkFFT.h:202
kiss_fft_cpx ComplexNumber
Definition: vtkFFT.h:52
abstract base class for most VTK objects
Definition: vtkObject.h:62
void PrintSelf(ostream &os, vtkIndent indent) override
Methods invoked by print to print information about the object including superclasses.
static void GenerateKernel2D(Array2D *kernel, const std::size_t n, const std::size_t m, WindowGenerator generator)
Given a window generator function, create a symmetric 2D kernel.
Definition: vtkFFT.h:220
static constexpr double Pi()
A mathematical constant.
Definition: vtkMath.h:103
static double BartlettGenerator(const std::size_t x, const std::size_t size)
Window generator functions.
Definition: vtkFFT.h:183
a simple class to control print indentation
Definition: vtkIndent.h:39
static void GenerateKernel1D(Array1D *kernel, const std::size_t n, WindowGenerator generator)
Given a window generator function, create a symmetric 1D kernel.
Definition: vtkFFT.h:209
static double SineGenerator(const std::size_t x, const std::size_t size)
Window generator functions.
Definition: vtkFFT.h:189
perform Discrete Fourier Transforms
Definition: vtkFFT.h:48
double(*)(const std::size_t, const std::size_t) WindowGenerator
Window generator functions.
Definition: vtkFFT.h:131
static vtkObject * New()
Create an object with Debug turned off, modified time initialized to zero, and reference counting on...
kiss_fft_scalar ScalarNumber
Definition: vtkFFT.h:51
static double Abs(const ComplexNumber &in)
Return the absolute value (also known as norm, modulus, or magnitude) of complex number.
Definition: vtkFFT.h:165
static double BlackmanGenerator(const std::size_t x, const std::size_t size)
Window generator functions.
Definition: vtkFFT.h:195
static double SquaredAbs(const ComplexNumber &in)
Return the squared absolute value of the complex number.
Definition: vtkFFT.h:171
static double HanningGenerator(const std::size_t x, const std::size_t size)
Window generator functions.
Definition: vtkFFT.h:177