使用FFTW,我想执行复数数组的IFFT,从文件" numbers.txt"中读取数据。 (它们以a + b * I的格式存储,每行一个复数)。我尝试了以下内容,但它不起作用:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#include <complex.h>
#include <fftw3.h>
int main(void)
{
fftw_complex *in;
fftw_complex *out;
float re,im;
int size;
printf("Insert size");
scanf("%d", &size);
FILE *file = fopen("numbers.txt", "r");
int i=0;
while(fscanf(file, "%f+%fi", &re, &im) > 0) {
in[i]=re+im*I;
i++;
}
fclose(file);
fftw_complex *out_cpx;
fftw_plan ifft;
out_cpx = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*size);
out = (double *) malloc(size*sizeof(double));
ifft = fftw_plan_dft_c2r_1d(size, out_cpx, out, FFTW_ESTIMATE); //Setup fftw plan
fftw_execute(ifft);
printf("Input: \tOutput:\n");
for(i=0;i<size;i++)
{
printf("%f\t%f\n",(in[i]),out[i]);
}
fftw_destroy_plan(ifft);
fftw_free(out_cpx);
free(out);
return 0;
}
样本输入是(每行一个数字):
0+0*I
0.01198+-0.0825632*I
1.32139e-05+1.94777e-05*I
-1.18289e-11+7.30045e-12*I
2.71773e-20+0*I
-1.18289e-11+-7.30045e-12*I
1.32139e-05+-1.94777e-05*I
0.01198+0.0825632*I
特别是,我在从文件中读取数据时遇到了问题。有人有什么建议吗?提前致谢
编辑:
经过一些改进之后,我现在正在使用这个经过修改的代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#include <complex.h>
#include <fftw3.h>
int main(void)
{
fftw_complex *in;
fftw_complex *out;
double re,im;
int size;
int i=0;
FILE *file;
fftw_plan ifft;
printf("Insert size");
if (scanf("%d", &size) != 1 || size < 1)
return 1;
in = fftw_malloc(sizeof(*in)*size);
out = fftw_malloc(sizeof(*out)*size);
file = fopen("numbers.txt", "r");
for (i = 0; i < size && fscanf(file, "%lf+%lf*I\n", &re, &im) == 2; i++)
{
in[i]= re+im*I;
}
fclose(file);
// Error if i != size?
ifft = fftw_plan_dft_1d(size, in, out, FFTW_BACKWARD, FFTW_ESTIMATE);
fftw_execute(ifft);
printf("Input: \tOutput:\n");
for(i=0; i<size; i++)
{
printf("%lf+%lfI\t%lf+%lfI\n", creal(in[i]), cimag(in[i]), creal(out[i]), cimag(out[i]));
}
fftw_destroy_plan(ifft);
fftw_free(in);
fftw_free(out);
//free(out);
return 0;
}
现在的问题是我总是得到一个实值变换的数组。我该如何解决?
答案 0 :(得分:3)
你有几个问题。 fftw_plan_dft_c2r_1d
的调用顺序如下:
逆变换将复杂输入(存储逻辑Hermitian数组的非冗余半部分)转换为实际输出,由下式给出:
fftw_plan fftw_plan_dft_c2r_1d(int n0, fftw_complex *in, double *out, unsigned flags);
因此,您有以下问题:
您永远不会分配fftw_complex *in
数组。它应该是
in = fftw_malloc(sizeof(*in)*size);
// And later
fftw_free(in);
不需要in_cpx
,因为in
很复杂。
建议fftw_malloc
使用out
。
fftw_complex
具有双精度,因此re
和im
也应如此。
检查scanf和fscanf的返回值。
更新如上面的chux所述,当i&gt; = size时突破循环。另外,检查以确保循环完成时i == size。
我没有c99可用,因此我无法访问新的built-in complex
type,但修复可能看起来像(未经过测试):
int main(void)
{
fftw_complex *in;
double *out;
double re,im;
int size;
int i=0;
FILE *file;
fftw_plan ifft;
printf("Insert size");
if (scanf("%d", &size) != 1 || size < 1)
return 1;
in = fftw_malloc(sizeof(*in)*size);
out = fftw_malloc(sizeof(*out)*size);
file = fopen("numbers.txt", "r");
for (i = 0; i < size && fscanf(file, "%lf+%lf*I\n", &re, &im) == 2; i++)
{
in[i]= re + im*I;
}
fclose(file);
// Error if i != size?
ifft = fftw_plan_dft_c2r_1d(size, in, out, FFTW_ESTIMATE); //Setup fftw plan
fftw_execute(ifft);
printf("Input: \tOutput:\n");
for(i=0; i<size; i++)
{
printf("%lf+i%lf\t%lf\n", creal(in[i]), cimag(in[i]), out[i]);
}
fftw_destroy_plan(ifft);
fftw_free(in);
fftw_free(out);
return 0;
}
答案 1 :(得分:1)
此
printf("%f\t%f\n",(in[i]),out[i]);
必须是
printf("%f + %f j\t%f + %f j\n", in[i][0], in[i][1], out[i][0], out[i][1]);
因为fftw_complex
只是
typedef double fftw_complex[2];
答案 2 :(得分:1)
代码没有为输入分配内存(这是主要问题)
fftw_complex *in;
...
in = malloc(size * sizeof *in);
// or
in = calloc(size, sizeof *in);
...
in[i]=re+im*I;
...
free(in);
while循环应检查== 2
而不是> 0
。还添加了空格以允许复数的间距。如果不起作用,建议OP提供样本输入。
// while(fscanf(file, "%f+%fi", &re, &im) > 0) {
while(fscanf(file, "%f +%f i", &re, &im) == 2) {
代码不会在循环i == size
之后检查。
建议更轻松地编码和维护malloc()
样式:
// out_cpx = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*size);
out_cpx = fftw_malloc(size * sizeof *out_cpx);
// out = (double *) malloc(size*sizeof(double));
out = malloc(size * sizeof *out);
替代格式可能提供更多信息
// printf("%f\t%f\n",(in[i]),out[i]);
printf("%e\t%e\n",(in[i]),out[i]);
强大的代码会检查scanf("%d", &size);
和malloc()
的返回值。
重新格式化代码会使其更容易理解。