输出中的 FFTW 交错零(不是结束填充)
FFTW interlaced zero's in output (not end padding)
我找不到记录的位置或类似的问题,但是当我执行包含超过 2k 个元素的 FFT 时,我的输出交错零,例如,如果我将 N 加倍到 4k,我的输出是 4k 个元素,2k数据点与 2k 个零交替,即 {...9413.5, 0.0, 9266.2, 0.0, ...}。谁能解释一下我忽略了什么,谢谢!
//testing the fftw compile with gcc fftw_test.c -lfftw3 -lm -o fftw_test
#include <stdlib.h>
#include <fftw3.h>
#include <math.h>
#define N 1024*4
int main(void)
{
double input[N] =
{/*This is filled with 4k elements representing a basic sine wave*/};
//declare
double *in;
fftw_complex *out;
fftw_plan my_plan;
//allocate and assign
in = (double*) fftw_malloc(sizeof(double) * N);
for (int i = 0; i < N; i++)
{
in[i] = input[i];
}
out = (fftw_complex*) fftw_malloc((sizeof(fftw_complex) * N) + 1);
my_plan = fftw_plan_dft_r2c_1d(N, in, out, FFTW_ESTIMATE);
//execute
fftw_execute(my_plan);
//print magnitude
FILE *log = fopen("log.txt", "w");
for (int i = 0; i < N; i++)
{
input[i] = sqrt(out[i][0]*out[i][0] + out[i][1]*out[i][1]);
fprintf(log, " %.01lf,", input[i]);
}
//exit
fclose(log);
fftw_destroy_plan(my_plan);
fftw_free(in);
fftw_free(out);
return 0;
}
代码是使用这个预先编写的 python 脚本生成的(我意识到它只生成 2k 点,我只是复制了两次):
#this program generates a sine wave and prints it to sine.txt
import numpy as np
import matplotlib.pylab as plt
file = open("sine.txt","w")
x = np.linspace(0, 2048, 2048)
y = [2048]
plt.plot(np.int16(np.sin(x/16)*2048 + 2048))
for i in x:
file.write(str(np.int16(np.sin(i/16)*2048+2048)))
file.write(", ")
file.close()
plt.show()
这是关键:
I realize it only generates 2k points, I just copied it twice
您创建了一个正弦波信号,其周期没有平均划分您的信号长度。因此,它的离散傅立叶变换具有所有频率的值(如果它均匀地划分信号长度,您将在 FFT 中看到只有两个非零元素)。但是随后您复制了信号,实际上创建了一个信号,其中 N
恰好是周期的两倍。因此,所有奇数 k
的频率内容为零。
如果您复制了四份信号,您会在每个非零分量之间找到三个零。如果你复制 8 份,你会发现 7 个零。在所有这些情况下,非零元素都是相同的,但按副本数缩放。
我找不到记录的位置或类似的问题,但是当我执行包含超过 2k 个元素的 FFT 时,我的输出交错零,例如,如果我将 N 加倍到 4k,我的输出是 4k 个元素,2k数据点与 2k 个零交替,即 {...9413.5, 0.0, 9266.2, 0.0, ...}。谁能解释一下我忽略了什么,谢谢!
//testing the fftw compile with gcc fftw_test.c -lfftw3 -lm -o fftw_test
#include <stdlib.h>
#include <fftw3.h>
#include <math.h>
#define N 1024*4
int main(void)
{
double input[N] =
{/*This is filled with 4k elements representing a basic sine wave*/};
//declare
double *in;
fftw_complex *out;
fftw_plan my_plan;
//allocate and assign
in = (double*) fftw_malloc(sizeof(double) * N);
for (int i = 0; i < N; i++)
{
in[i] = input[i];
}
out = (fftw_complex*) fftw_malloc((sizeof(fftw_complex) * N) + 1);
my_plan = fftw_plan_dft_r2c_1d(N, in, out, FFTW_ESTIMATE);
//execute
fftw_execute(my_plan);
//print magnitude
FILE *log = fopen("log.txt", "w");
for (int i = 0; i < N; i++)
{
input[i] = sqrt(out[i][0]*out[i][0] + out[i][1]*out[i][1]);
fprintf(log, " %.01lf,", input[i]);
}
//exit
fclose(log);
fftw_destroy_plan(my_plan);
fftw_free(in);
fftw_free(out);
return 0;
}
代码是使用这个预先编写的 python 脚本生成的(我意识到它只生成 2k 点,我只是复制了两次):
#this program generates a sine wave and prints it to sine.txt
import numpy as np
import matplotlib.pylab as plt
file = open("sine.txt","w")
x = np.linspace(0, 2048, 2048)
y = [2048]
plt.plot(np.int16(np.sin(x/16)*2048 + 2048))
for i in x:
file.write(str(np.int16(np.sin(i/16)*2048+2048)))
file.write(", ")
file.close()
plt.show()
这是关键:
I realize it only generates 2k points, I just copied it twice
您创建了一个正弦波信号,其周期没有平均划分您的信号长度。因此,它的离散傅立叶变换具有所有频率的值(如果它均匀地划分信号长度,您将在 FFT 中看到只有两个非零元素)。但是随后您复制了信号,实际上创建了一个信号,其中 N
恰好是周期的两倍。因此,所有奇数 k
的频率内容为零。
如果您复制了四份信号,您会在每个非零分量之间找到三个零。如果你复制 8 份,你会发现 7 个零。在所有这些情况下,非零元素都是相同的,但按副本数缩放。