Isis 3 Programmer Reference
FourierTransform.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 
8 #include "FourierTransform.h"
9 
10 using namespace std;
11 
12 namespace Isis {
14  FourierTransform::FourierTransform() {};
15 
17  FourierTransform::~FourierTransform() {};
18 
27  std::vector< std::complex<double> >
28  FourierTransform::Transform(std::vector< std::complex<double> > input) {
29  // data length must be a power of two
30  // any extra space is filled with zeroes
31  int n = NextPowerOfTwo(input.size());
32  vector< std::complex<double> > output(n);
33  input.resize(n);
34 
35  // rearrange the data to fit the iterative algorithm
36  // which will apply the transform from the bottom up
37  for(int i = 0; i < n; i++) {
38  if(output[i] == 0.0) {
39  int j = BitReverse(n, i);
40  output[i] = input[j];
41  output[j] = input[i];
42  }
43  }
44 
45  // do the iterative fft calculation by first combining
46  // subarrays of length 2, then 4, 8, etc.
47  for(int m = 1; m < n; m *= 2) {
48  complex<double> Wm(polar(1.0, -1.0 * PI / m)); // Wm = e^(-PI/m *i)
49  for(int k = 0; k < n; k += 2 * m) {
50  // W = Wm^j, the roots of unity for x^m=1
51  complex<double> W(1.0);
52  for(int j = 0; j < m; j++) {
53  complex<double> t = W * output[k+j+m]; // the "twiddle" factor
54  complex<double> u = output[k+j];
55  output[k+j] = u + t; // a[k+j]+Wm^j*a[k+j+m]
56  output[k+j+m] = u - t; // a[k+j]+Wm^(j+m)*[k+j+m] = a[k+j]-Wm^j*[k+j+m]
57  W = W * Wm;
58  }
59  }
60  }
61 
62  return output;
63  }
64 
65 
74  std::vector< std::complex<double> >
75  FourierTransform::Inverse(std::vector< std::complex<double> > input) {
76  // Inverse(input) = 1/n*conj(Transform(conj(input)))
77  int n = input.size();
78  std::vector< std::complex<double> > temp(n);
79  for(int i = 0; i < n; i++) {
80  temp[i] = conj(input[i]);
81  }
82 
83  std::vector< std::complex<double> > output = Transform(temp);
84 
85  for(int i = 0; i < n; i++) {
86  output[i] = conj(output[i]) / ((double)n);
87  }
88 
89  return output;
90  }
91 
100  bool FourierTransform:: IsPowerOfTwo(int n) {
101  while(n > 1) {
102  if(n % 2 == 1) return false;
103  n /= 2;
104  }
105 
106  return true;
107  }
108 
116  int FourierTransform:: lg(int n) {
117  int k = 0;
118  while(n > 1) {
119  n = n / 2;
120  k++;
121  }
122  return k;
123  }
124 
137  int FourierTransform::BitReverse(int n, int x) {
138  double ans = 0.0;
139  double a = 1.0;
140  while(x > 0) {
141  if(x % 2 == 1) {
142  ans += a;
143  x -= 1;
144  }
145  x = x / 2;
146  a = a / 2.0;
147  }
148 
149  return(int)(ans * n / 2);
150  }
151 
160  int FourierTransform::NextPowerOfTwo(int n) {
161  if(IsPowerOfTwo(n)) return n;
162  return(int)pow(2.0, lg(n) + 1);
163  }
164 }
Isis::PI
const double PI
The mathematical constant PI.
Definition: Constants.h:40
Isis::Transform
Pixel transformation.
Definition: Transform.h:72
std
Namespace for the standard library.
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16