FFT无法重组结果?

时间:2013-04-28 22:57:52

标签: c math fft scientific-computing

所以基本上我有一个函数来计算给定向量大小为N的复杂离散傅立叶级数。(所以我已经提供了向量y,我必须找到x) 该代码使用Daniel-Lanczo的FFT算法,在N = 2 ^ m时完美地工作。但是,当我用N = 3.2 ^ m或N = 5.2 ^ m的东西进行测试时,我开始遇到问题。到目前为止我考虑过的最简单的是N = 6。

if((N%3)==0 && (N%2)==0 && (N%5)!=0)

是使N = 6落入该特定if语句的条件。在此内部,我首先将y的元素分成y(y_e)的偶数条目,然后将y(y_o)的奇数条目分开,并将它们加载到另一个大小为2 * N的数组w中。一旦找到x,我也以类似的方式将x_e和x_o分开,并将它们加载到w的不同部分。

该算法的工作原理是将N分成越来越小的分量,然后对它们进行傅里叶变换。例如,如果N = 4,则将其分成2个大小为2的向量(即y_e和y_o),现在对于大小N = 2调用函数两次,然后返回结果。然后将结果组合/构建以获得最终的傅里叶级数。

N = 6的问题是它将它分成2,所以我有2个向量y_e和y_o,大小为3,所以当我从内部调用函数时,现在大小为3而不是6 ,它落入下面的第一个if语句(如果N == 3)并且直接矩阵乘以找到系列。请注意,我在“If N == 3”中调用了这个向量'x'现在应该返回到我调用函数的位置

FastDFS(x, y_e, w, Wp, (N/2), 1);

(其中FastDFS只是函数的名称)并再次打印出结果“x”。但由于某种原因,它没有这样做。它告诉我x的条目是[0 + 0i,0 + 0i,0 + 0i],即它是空的。我不明白为什么会发生这种情况。我试图创建一个新的向量,在找到N = 3的x之后为它分配'x'的条目,然后在N = 6的情况下打印新的向量并且它有效..但它不切实际不起作用当我尝试更高的N,如12或24时。

有谁知道为什么可能将x的条目设置为零?

我明白这很令人困惑,但如果有人可以提供帮助,我会非常感激!

if(N==3)
{
    Cn=MakeCn(3);

    x=complex_matrix_vector_multiply(Cn, y, 3, 3, 3, 1);
    print_complex_vector(x, 3);

    /*for(i=2*N;i<=3*N-1;i++)
    {
        for(j=0;j<=N-1;j++)
        {
            w[i]=x[j];
            i++;
        }
    }*/
    //printf("\ni am here thuis is w\n");
    //print_complex_vector(w, 12);
}


if((N%3)==0 && (N%2)==0 && (N%5)!=0)
{   
    double complex *x_e,*x_o;
    x_e=make_complex_vector(x_e, N/2);
    x_o=make_complex_vector(x_o, N/2);
    printf("whatup BBBB");
    int j=0,k=0;
    double complex *y_e,*y_o;
    printf("\nthis is N: %d\n",N);
    print_complex_vector(y, N);
    y_e=make_complex_vector(y_e,N/2);
    y_o=make_complex_vector(y_o,N/2);

    /*********************************************************************************************************
     Here were are going to separate the even and odd elements of y into the y_e and y_o. 
     *********************************************************************************************************/

    for(i=0;i<=N-1;i++)
    {
        if(i%2==0)
        {
            y_e[j]=y[i];
            j++;
        }
        else 
        {
            y_o[k]=y[i];
            k++;
        }

    }
    printf("\n These are vectors y_e and y_o: \n");
    print_complex_vector(y_e, N/2);
    print_complex_vector(y_o, N/2);

    /*********************************************************************************************************
     Here were are going to load the even and odd elements of y into the w. w[0...N/2-1]=y_e and w[N/2...N-1]=y_o 
     *********************************************************************************************************/

    for(k=0;k<=(N/2)-1;k++)
    {
        for(i=0;i<=(N-1);i++)
        {

            if(i%2==0)
            {   
                w[k]=y[i];
                k++;
            }
        }
    }

    for(j=N/2;j<=N-1;j++)
    {
        for(i=0;i<=(N-1);i++)
        {

            if(i%2!=0)
            {
                w[j]=y[i];
                j++;
            }   
        }
    }
    printf("\n This is the vector w: \n");
    print_complex_vector(w, N);

    /*********************************************************************************************************
     Here were are going to call FastDFS twice within itself for N/2 with x, y_e, y_o and w. 
     The values of x that are found are the respective x_e and x_o that we load into w. 
     w[N...3N/2-1]=x_e and w[3N/2...2N-1]=x_o
     *********************************************************************************************************/

    Cn2=MakeCn(N/2);

    FastDFS(x, y_e, w, Wp, (N/2), 1);
    // printf("\n w in we ljkdgj\n");
    // print_complex_vector(w, 2*N);
    /* for(i=N;i<=(3*N/2)-1;i++)
     {
     for(j=0;j<=N-1;j++)
     {
     w[i]=x[j];
     i++;
     }
     }*/
    printf("\n here:\n");
    print_complex_vector(x, N);


    for(j=0;j<=(N/2)-1;j++)
    {
        for(i=N;i<=(3*N/2)-1;i++)
        {
            x_e[j]=w[i];
            j++;
        }   
    }
    printf("\n this is x_e:\n");
    print_complex_vector(x_e, N/2);

    FastDFS(x, y_o, w, Wp, (N/2), 1);

    // print_complex_vector(w, 2*N);
    for(j=0;j<=(N/2)-1;j++)
    {
        for(i=N;i<=(3*N/2)-1;i++)
        {
            x_o[j]=w[i];
            j++;
        }   
    }
    printf("\n this is x_o:\n");
    print_complex_vector(x_o, N/2);

    for(k=N;k<=(3*N/2)-1;k++)
    {
        for(j=0;j<=(N/2)-1;j++)
        {

            w[k]=x_e[j];
            k++;
        }
    }

    for(k=(3*N/2);k<=2*N-1;k++)
    {
        for(j=0;j<=(N/2)-1;j++)
        {

            w[k]=x_o[j];
            k++;
        }
    }
    print_complex_vector(w, 2*N);

    /*********************************************************************************************************
     Here were are going to find the final x_j and x_j+N/2 by x_j=[x_e]+W_n^j[x_o] and x_j+N/2+Wn^j+N/2[x_o]
     This is the final answer for the Discrete Fourier Series of N even.
     We do not use x_e and x_o explicitly but use different parts of w. 
     *********************************************************************************************************/

    F=cos(2*pi/N)+I*sin(2*pi/N);


    for(i=0;i<=(N/2)-1;i++)
    {
        for(j=N;j<=2*N-1;j++)
        {   
            x[i]=w[j]+((cpow(F, i))*w[(j+N/2)]);
            i++;
        }
    }

    for(i=0;i<=(N/2)-1;i++)
    {
        for(k=N;k<=(2*N)-1;k++)
        {
            x[(i+N/2)]=w[k]+((cpow(F, (i+N/2)))*w[k+N/2]);
            i++;
        }
    }

    /*for(i=0;i<=(N/2)-1;i++)
     {

     x[i]=x_e[i]+((cpow(F, i))*x_o[i]);
     x[(i+N/2)]=x_e[i]+((cpow(F, (i+N/2)))*x_o[i]);


     }
     */

    printf("\n\nThe Final Discrete Fourier Series, for N = %d, is:\n\n",N);

    for (i=0; i<=N-1; i++) 

    {
        printf ("%9.4f+%.4fi  \n", creal(x[i]),cimag(x[i]));

    }


}

1 个答案:

答案 0 :(得分:0)

该行

x=complex_matrix_vector_multiply(Cn, y, 3, 3, 3, 1);

将使用计算结果覆盖x的本地值。我假设x是一个指针,最初该指针指示了你想要结果的位置。但在此行之后,它指向其他位置,并且您最初传入的x将无法从函数内部访问。

您可能希望使用某种形式的乘法,将其输出写入预先分配的数组。或者您希望使用临时指针存储结果,然后一次从该结果复制到x一个元素。请记住free之后的临时结果。

将函数标题添加到您粘贴的代码片段可能会使这些事情更加清晰,并且仍然会让那些可能希望将来阅读它的人更清楚。

我没有仔细研究其余的实现,但是行Cn2=MakeCn(N/2);看起来多余。你没有使用那个价值,是吗?