[英]FFT of an array of complex numbers
我想使用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;
}
現在的問題是,我總是得到一個實值轉換數組。 我該如何解決?
您有幾個問題。 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
數組中分配fftw_complex *in
。 它應該是
in = fftw_malloc(sizeof(*in)*size); // And later fftw_free(in);
不需要in_cpx
,因為in
很復雜。
建議也將fftw_malloc
用於out
。
fftw_complex
是雙精度的,因此re
和im
應該也是如此。
您的printf
不適用於C99復數
檢查scanf和fscanf的返回值。
正如chux所說的那樣更新 ,當i> = size時就跳出循環。 另外,在循環完成時檢查以確保i == size。
我沒有可用的c99,因此無法訪問新的內置complex
類型 ,但是修復可能看起來像(未經測試):
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;
}
這個
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];
代碼沒有為輸入分配內存(這是主要問題)
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 +%fi", &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);
的返回值scanf("%d", &size);
和malloc()
。
重新格式化代碼將使其更容易理解。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.