Isis 3 Programmer Reference
FourierTransform.cpp
1
6/* SPDX-License-Identifier: CC0-1.0 */
7
8#include "FourierTransform.h"
9
10using namespace std;
11
12namespace Isis {
15
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
101 while(n > 1) {
102 if(n % 2 == 1) return false;
103 n /= 2;
104 }
105
106 return true;
107 }
108
117 int k = 0;
118 while(n > 1) {
119 n = n / 2;
120 k++;
121 }
122 return k;
123 }
124
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
161 if(IsPowerOfTwo(n)) return n;
162 return(int)pow(2.0, lg(n) + 1);
163 }
164}
int lg(int n)
This function returns the floor of log2(n)
std::vector< std::complex< double > > Inverse(std::vector< std::complex< double > > input)
Applies the inverse Fourier transform on the input data and returns the result.
int BitReverse(int n, int x)
Reverses the binary representation of the input integer in the number of bits specified.
std::vector< std::complex< double > > Transform(std::vector< std::complex< double > > input)
Applies the Fourier transform on the input data and returns the result.
FourierTransform()
Constructs the FourierTransform object.
bool IsPowerOfTwo(int n)
Checks to see if the input integer is a power of two.
int NextPowerOfTwo(int n)
This function returns the next power of two greater than or equal to n.
~FourierTransform()
Destroys the FourierTransform object.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
const double PI
The mathematical constant PI.
Definition Constants.h:40
Namespace for the standard library.