簡體   English   中英

復數數組的FFT

[英]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); 

因此,您遇到以下問題:

  1. 您永遠不會fftw_complex *in數組中分配fftw_complex *in 它應該是

     in = fftw_malloc(sizeof(*in)*size); // And later fftw_free(in); 
  2. 不需要in_cpx ,因為in很復雜。

  3. 建議也將fftw_malloc用於out

  4. fftw_complex是雙精度的,因此reim應該也是如此。

  5. 您的printf 不適用於C99復數

  6. 檢查scanf和fscanf的返回值。

  7. 正如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];
  1. 代碼沒有為輸入分配內存(這是主要問題)

     fftw_complex *in; ... in = malloc(size * sizeof *in); // or in = calloc(size, sizeof *in); ... in[i]=re+im*I; ... free(in); 
  2. While循環應檢查== 2而不是> 0 還添加了空格以允許復數間距。 如果這不起作用,建議OP提供示例輸入。

     // while(fscanf(file, "%f+%fi", &re, &im) > 0) { while(fscanf(file, "%f +%fi", &re, &im) == 2) { 
  3. 代碼不檢查循環i == size

  4. 建議更容易編碼和維護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); 
  5. 備用格式可能更有用

     // printf("%f\\t%f\\n",(in[i]),out[i]); printf("%e\\t%e\\n",(in[i]),out[i]); 
  6. 健壯的代碼將檢查scanf("%d", &size);的返回值scanf("%d", &size); malloc()

  7. 重新格式化代碼將使其更容易理解。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM