与实施库利FFT的故障

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了与实施库利FFT的故障相关的知识,希望对你有一定的参考价值。

我做与FFT的帮助两个整型信号的卷积,但不知何故,我无法得到它的权利。我不知道如果我的FFT的实现是正确的。特别是数学的一部分。

大编辑:我现在发布的所有代码。我的道歉不与它开始。我相信只有在FFT部分误差,但可能有更多的问题,我忽略了。我知道代码是混乱和不干净。一切都有点分散,能够以更简单和更清洁的方式进行编程,但我一点测试一下。至于输入读取命令行的两个信号。建立为一个数字指示该信号是多大并呈现为一个整数阵列当量2的信号:[1,-1]和10:[0,0,0,1,1,1,1,0,0, 0]。然后,它应该由他们两个然后做逐位乘法执行FFT做对信号的卷积。随着对所得到的信号中的逆FFT。与长度再次打印,然后在阵列consiting整数。印刷本身是正确的,但所得到的数组中的值是不正确的。我希望这是所有更清楚一点,现在我再次道歉,并感谢您的帮助迄今为止。

#include <stdio.h>
#include <stdlib.h>
#include <math.h> 
#include <complex.h>

double PI;

int *readSignal(int *len) {    //reads the signal
    int *x;
    char c;
    scanf("%d:", len);
    x = calloc(*len, sizeof(int));
    do c = getchar(); while (c != '[');
    if (len > 0) {
       scanf("%d", &x[0]);
       for (int i=1; i < *len; i++) scanf(",%d", &x[i]);
    }
    do c = getchar(); while (c != ']');
    return x;
}

void printSignal(int len, int *x) { //prints the signal
    printf("%d: [", len);
    if (len > 0) {
        printf("%d", x[0]);
        for (int i=1; i < len; i++) 
            printf(",%d", x[i]);
        }
        printf("]
");
    }

void *padSignal(int len, int lenSig, int *x) {  //ensures that the signal is of size 2^n by padding it with 0's
    int *padded;
    padded = calloc(len, sizeof(int));
    for (int i=0; i < lenSig; i++) {
        padded[i] = x[i];
    }
    return padded;
}

void fft(double complex signal[], int length, int power) {
    if (length == 1) {
        return;
    }
    double complex *signalODD = calloc((length/2+1), sizeof(double complex));
    double complex *signalEVEN = calloc((length/2+1), sizeof(double complex));
    int index1 = 0;
    int index2 = 0;
    for(int i = 0; i < length; i++) {
        if(i % 2 ==0) {
            signalEVEN[index1] = signal[i];
            index1++;
        }
        else {
            signalODD[index2] = signal[i];
            index2++;
        }
    }
    fft(signalEVEN,length/2, power+1);
    fft(signalODD,length/2, power+1);
    for(int i = 0; i<length/2-1; i++) {
        signal[i] = signalEVEN[i] + cexp((I*2*PI*i)/length)*signalODD[i];
        signal[i+length/2] = signalEVEN[i]-cexp((I*2*PI*i)/length)*signalODD[i];
    }
    free(signalODD);
    free(signalEVEN);
}

void ifft(double complex signal[], int length, int power) {
    if (length == 1) {
        return;
    }
    double complex *signalODD = calloc((length/2+1), sizeof(double complex));
    double complex *signalEVEN = calloc((length/2+1), sizeof(double complex));
    int index1 = 0;
    int index2 = 0;
    for(int i = 0; i < length; i++) {
        if(i % 2 ==0) {
            signalEVEN[index1] = signal[i];
            index1++;
        }
        else {
            signalODD[index2] = signal[i];
            index2++;
        }
    }
    fft(signalEVEN,length/2, power+1);
    ifft(signalODD,length/2, power+1);
    for(int i = 0; i<length/2-1; i++) {
        signal[i] = signalEVEN[i] + cexp((I*-2*PI*i)/length)*signalODD[i];
        signal[i+length/2] = signalEVEN[i]-cexp((I*-2*PI*i)/length)*signalODD[i];
    }
    free(signalODD);
    free(signalEVEN);
}


int checkPowerofTwo(double len) { //checks for the closed power of 2
    double x = 1;
    while(len > pow(2,x)) {
        x++;
    }
    return pow(2,x);
}

int main(int argc, char *argv[]) {
  int lenH, *H;
  int lenX, *X;
  int *paddedX;
  int *paddedH;
  double length;
  H=readSignal(&lenH); //reads in the signal H
  X=readSignal(&lenX); //reads in signal X

  length = lenH+lenX-1;
  paddedH=padSignal((length),lenH,H); //pads the signal to the length
  paddedX=padSignal((length),lenX,X); // pads the signal to the length

  double complex *signalX = calloc(length, sizeof(double complex)); //creats a complex signal X and fills it with paddedX
  for (int i = 0; i<length; i++) {
      signalX[i] = paddedX[i];
  }
  double complex *signalH = calloc(length, sizeof(double complex)); // same for H
  for (int i = 0; i<length; i++) {
      signalH[i] = paddedH[i];
  }
  fft(signalX, length, 1); //performs the fast fourier transform on X
  fft(signalH,length, 1); // performs the fast fourier transfom on H
  double complex *signalY = calloc(length, sizeof(double complex)); //makes complex signal Y
  for (int i = 0; i<length; i++) { //performs the convolution
      signalY[i] = signalX[i]*signalH[i];
  }
  ifft(signalY, length,1);

  int *output = calloc(length, sizeof(int)); //creates the final output signal
  for (int i = 0; i<length; i++) {
      output[i] = creal(signalY[i]);
  }
  printSignal(length,output);

  free(signalX);
  free(signalH);
  free(signalY);
  free(H);
  free(X);
  free(paddedH);
  free(paddedX);
  free(output);

  return 0;
}
答案

在:

if(i % 2 ==0 && i != 0)

为什么你排除i == 0?改变,在这两个if(i % 2 ==0)fftifft

在这两个fftifft,行:

for(int i = 0; i<lenght/2-1; i++) {

应该:

for(int i = 0; i<lenght/2; i++) {

ifft,递归不慎使用fft

fft(signalEVEN,lenght/2, power+1);
fft(signalODD,lenght/2, power+1);

改变那些ifft

calloc通话不需要这么多的空间:

calloc((lenght/2 + 1), sizeof(double complex));

这可以是:

calloc((lenght/2), sizeof(double complex));

此外,正确拼写的是“长度”。

有了这些固定的,fftifft程序出现了一些粗浅的情况下工作。

以上是关于与实施库利FFT的故障的主要内容,如果未能解决你的问题,请参考以下文章

FFT的最优算法是啥?以及其代码(C语言),谢谢!

FFT(快速傅里叶变换)

fft窄带高分辨率算法

利用FFT计算非平稳随机信号的WVD分布

基于FPGA的64点fft变换verilog开发

故障诊断分析基于matlab FFT轴承故障诊断含Matlab源码 1397期