/**
* 1D-IDFT [Inverse Discrete Fourier Transform]
* [How to Use]
* <case:>
* Fo[T] = {};
* Fn[N] = {...};
* dft_1d(&Fo, &Fn, T, N);
* [theorem::definitions]
* Fo meanings Original Function
* Fn meanings Fourier Basis at [n]
* pi meanings π
* T meanings Periodic of Fo
* N meanings Slice of Frequency
* Wn meanings Angular Frequency of Basis Fn is Wn = ((2*pi*n)/T)
* [theorem::formula]
* Fo[t] = sum_{n=0}^{N-1} x Fn[t], 0<=n<N
* Fn[t] = sum_{t=0}^{T-1} x Fo[t] * exp( -i * ((2*pi*n)/T) * t), 0<=t<T
* = sum_{t=0}^{T-1} x Fo[t] * (An * cos(Wn * t) + Bn * sin(Wn * t)), 0<=t<T
* = All_in_one(An) * cos(Wn * t) + All_in_one(Bn) * sin(Wn * t), 0<=t<T
* So:
* An = Re(Fn[t]); Bn = Im(Fn[t])
* [logistic]
* {
* result = []; // as byte array
* // do TDD:
* for t in range(T) {
* Re = 0; Im = 0;
* // do FDD:
* for n in Range(N) {
* Wn = (2 * pi * n) / T;
* An = Re(Fn[n]);
* Bn = Im(Fn[n]);
* result[t] += Fn[n].to_value(Wn, An, Bn);
* }
* }
* return result;
* }
* @param Fo Original Function input array
* (already sampled by T as count-of-time-slice)
* @param Fn Fourier Basis
* (already sampled by N as count-of-frequency-slice)
* @param T Periodic of Fo, Number of Time Slice
* @param N Number of Frequency Slice
*/
现在思路有了,只需要以代码实现即可:
#include "stdio.h"
#include "math.h"
#define PI 3.1415926f
typedef struct FBasis {
double re_;
double im_;
double w_;
} FBasis;
void dft_1d(double *Fo, FBasis *Fn, size_t T, size_t N) {
for (int n = 0; n < N; ++n) {
double An = 0;
double Bn = 0;
double Wn = (2 * PI * n) / T;
for (int t = 0; t < T; ++t) {
An += cos(Wn * t) * Fo[t];
Bn += sin(Wn * t) * Fo[t];
}
FBasis e_ = {An, Bn, Wn};
Fn[n] = e_;
}
}
void idft_1d(double *Fo, FBasis *Fn, size_t T, size_t N) {
for (int t = 0; t < T; ++t) {
for (int n = 0; n < N; ++n) {
FBasis e_ = Fn[n];
Fo[t] += (e_.re_ * cos(e_.w_ * t) + e_.im_ * sin(e_.w_ * t)) / N;
}
}
}
写完后简单测试一下:
int main(void) {
FBasis Fn[6] = {};
double Fo[6] = {1, 2, 3, 4, 5, 6};
double iFo[6] = {};
size_t T = sizeof(Fo) / sizeof(double);
size_t N = sizeof(Fn) / sizeof(FBasis);
printf("\n Original_data: \n");
for (int t = 0; t < T; ++t) {
printf("%f ", Fo[t]);
}
printf("\n DFT_result: \n");
dft_1d(Fo, Fn, T, N);
for (int n = 0; n < N; ++n) {
printf("%f + i %f \n", Fn[n].re_, Fn[n].im_);
}
printf("\n IDFT_result: \n");
idft_1d(iFo, Fn, T, N);
for (int t = 0; t < T; ++t) {
printf("%f ", iFo[t]);
}
return 0;
}
得到结果和标准几近相同:
Original data:
1.000000 2.000000 3.000000 4.000000 5.000000 6.000000
DFT_result:
21.000000 + i 0.000000
-3.000003 + i -5.196152
-3.000002 + i -1.732048
-3.000000 + i -0.000002
-2.999996 + i 1.732057
-2.999979 + i 5.196158
IDFT_result:
1.000003 2.000000 2.999999 3.999999 4.999999 6.000000