zoukankan      html  css  js  c++  java
  • 快速傅里叶变换C++递归算法实现

    快速傅里叶变换C++递归算法实现

     

        网上有些算法资料经测试运行结果是错误的,虽然代码的使用的是非递归形式。为了方便验证快速傅里叶变换的准确性,我提供了自己设计的递归算法。

      基于时域抽取的“基2”快速傅里叶变换算法代码:

        Fouier.h文件:

    #pragma once
    #include"Complex.h"
    class Fouier
    {
        Complex * data;
        void fft(int start,int step,int len);
        Complex W(int k,int n);//e^(-i*2*pi*k/n)
    public:
        Fouier(void);
        ~Fouier(void);
        
        void fft();
    };

        Fouier.c文件:

    #include "Fouier.h"
    #include<iostream>
    using namespace std;
    #include<cmath>
    #include<ctime>
    #define DATALEN 32
    #define KEYVALUE 10000 //生成随机浮点数的值,保证分子和分母在这个值之内
    #define PI 3.14159265358979323846
    Fouier::Fouier(void)
    {
        data=new Complex[DATALEN];
        srand(unsigned int(time(0)));
        cout<<"源数据:"<<endl;
        for(int i=0;i<DATALEN;i++)
        {
            data[i]=(rand()%(KEYVALUE))/(double)(rand()%(KEYVALUE)+1);
            if(i%5==0&&i!=0)
                cout<<endl;
            cout<<data[i]<<" ";
        }
        cout<<endl;
    }


    Fouier::~Fouier(void)
    {
        delete [] data;
    }
    Complex Fouier:: W(int k,int n)//欧拉公式
    {
        double alpha=-2*PI*k/n;
        return Complex(cos(alpha),sin(alpha));
    }
    void Fouier::fft(int start,int step,int len)
    {
        if(len==1)//一个元素
        {
            //一个元素不需要变换
            return ;
        }
        fft(start,step*2,len/2);//X1(k)
        fft(start+step,step*2,len/2);//X2(k)
        Complex X1,X2;
        for(int i=0;i<len/2;i++)
        {
            X1=data[start+step*i*2];
            X2=data[start+step*(i*2+1)];
            //计算X(k):k=0~N/2-1
            data[start+step*i]=X1+W(i,len)*X2;
            //计算X(k):k=N/2~N-1
            data[start+step*(i+len/2)]=X1-W(i,len)*X2;
        }
    }
    void Fouier::fft()
    {
        fft(0,1,DATALEN);
        cout<<"变换后数据:"<<endl;
        for(int i=0;i<DATALEN;i++)
        {
            if(i%5==0&&i!=0)
                cout<<endl;
            cout<<data[i]<<" ";
        }
    }

      Complex.h文件:

    #pragma once
    #include<iostream>
    using namespace std;
    class Complex//a+b*i
    {
        double a;//实数部分
        double b;//虚数部分
    public:
        Complex(double a=0,double b=0);
        //+操作
        friend Complex operator +(Complex &x,Complex &y);
        friend Complex operator +(double x,Complex &y);
        friend Complex operator +(Complex &x,double y);
        //-操作
        friend Complex operator -(Complex &x,Complex &y);
        friend Complex operator -(double x,Complex &y);
        friend Complex operator -(Complex &x,double y);
        //*操作
        friend Complex operator *(Complex &x,Complex &y);
        friend Complex operator *(double x,Complex &y);
        friend Complex operator *(Complex &x,double y);
        //=操作
        Complex operator =(Complex &x);
        Complex operator =(double x);
        //<<操作
        friend ostream & operator<<(ostream&out,Complex&c);

        ~Complex(void);
    };

        Complex.c文件:

    #include "Complex.h"

    Complex::Complex(double a,double b)//虚部默认是0
    {
        this->a=a;
        this->b=b;
    }


    Complex::~Complex(void)
    {
    }

    Complex operator +(Complex &x,Complex &y)
    {
        return Complex(x.a+y.a,x.b+y.b);
    }
    Complex operator +(double x,Complex &y)
    {
        return Complex(x+y.a,y.b);
    }
    Complex operator +(Complex &x,double y)
    {
        return Complex(x.a+y,x.b);
    }

    Complex operator -(Complex &x,Complex &y)
    {
        return Complex(x.a-y.a,x.b-y.b);
    }
    Complex operator -(double x,Complex &y)
    {
        return Complex(x-y.a,-y.b);
    }
    Complex operator -(Complex &x,double y)
    {
        return Complex(x.a-y,x.b);
    }

    Complex operator *(Complex &x,Complex &y)
    {
        return Complex(x.a*y.a-x.b*y.b,x.a*y.b+x.b*y.a);
    }
    Complex operator *(double x,Complex &y)
    {
        return Complex(x*y.a,x*y.b);
    }
    Complex operator *(Complex &x,double y)
    {
        return Complex(x.a*y,x.b*y);
    }

    Complex Complex::operator =(Complex &x)
    {
        a=x.a;
        b=x.b;
        return *this;
    }
    Complex Complex::operator =(double x)
    {
        a=x;
        b=0;
        return *this;
    }
    ostream & operator<<(ostream&out,Complex&c)
    {
        if(c.a!=0||c.a==0&&c.b==0)
            out<<c.a;
        if(c.b!=0)
        {
            if(c.b>0)
                out<<"+";
            if(c.b!=1)
                out<<c.b;
            out<<"i";
        }
        return out;
    }

        main.c文件:

    #include<iostream>
    using namespace std;
    #include"Fouier.h"

    int main()
    {
        Fouier f;
        f.fft();
        return 0;
    }

        如有错误,欢迎批评指正!

        参考资料:http://zhoufazhe2008.blog.163.com/blog/static/63326869200971010421361/

           维基百科:http://zh.wikipedia.org/wiki/%E5%BF%AB%E9%80%9F%E5%82%85%E7%AB%8B%E5%8F%B6%E5%8F%98%E6%8D%A2

  • 相关阅读:
    如何在windows下安装GIT
    TortoiseGit 安装
    高并发大流量专题---3、前端优化(减少HTTP请求次数)
    高并发大流量专题---2、流量优化(防盗链处理)
    高并发大流量专题---1、高并发大流量解决方案总结
    yii2和laravel比较
    php开发面试题---日常面试题1
    php开发面试题---禁用cookie之后,如何使用session
    剑指offer---4、序列化二叉树
    北风设计模式课程---20、UML类图介绍
  • 原文地址:https://www.cnblogs.com/fanzhidongyzby/p/2613208.html
Copyright © 2011-2022 走看看