理解FFT之一 复数


最近在看FFT的内容。参考了2个资料,一个是CLRS,一个是一本不知名的算法书。

都是以多项式为切入口接入FFT。

思路大致是,多项式有2中表达方式:系数,以及值对。

值对的表达方式非常有利于多项式之间的相互运算,同时也需要二者之间的相互转化。

其中一个简化计算的思路就是巧妙的选取x的值,减少计算量。

这就涉及到复数的使用。遂开始写一个复数的类。用来实现和验证fft算法。

算是自己第一个动手造的轮子。

代码比较丑陋,以后再慢慢改吧。

#ifndef MYCOMPLEX_H
#define MYCOMPLEX_H

#include <math.h>
#include <iostream>
using namespace std;

namespace MyComplex
{

#define PI 3.1415926

    struct mycomplex
    {
        double r, theta;
        mycomplex(const double& rin =0, const double& thetain=0) : r(rin), theta(thetain){};
        double re() const;
        double im() const;
        void fromReIm(double re, double im);
        bool operator==(const mycomplex& c) const;
        const mycomplex& operator=(const mycomplex& c);
        const mycomplex operator+(const mycomplex& c) const;
        const mycomplex operator-(const mycomplex& c) const;
        const mycomplex operator*(const mycomplex& c) const;
        const mycomplex operator/(const mycomplex& c) const;
        const mycomplex& operator+=(const mycomplex& c);
        const mycomplex& operator-=(const mycomplex& c);
        const mycomplex& operator*=(const mycomplex& c);
        const mycomplex& operator/=(const mycomplex& c);
        const mycomplex operator-() const;
        const mycomplex pow(double p) const;
        const mycomplex conj()const;

        ostream& print_p(ostream& os);
    private:
        void validate();
        //ostream& operator<<(ostream &os);
    };

    double mycomplex::re() const
    {
        return r*cos(theta);
    }

    double mycomplex::im() const
    {
        return r*sin(theta);
    }

    void mycomplex::fromReIm(double re, double im)
    {
        r = sqrt(re*re + im*im);
        if (re == 0.0)
        {
            if (im ==0.0)
            {
                theta = 0;
            }
            else
            {
                theta = (im > 0) ? (PI / 2) : (PI / 2 * 3);
            }
        }
        else
        {
            if (re<0)
            {
                theta = PI + atan(im / re);
            }
            if (re>0 && im<=0)
            {
                theta = 2 * PI + atan(im / re);
            }
            if (re>0 && im>=0)
            {
                theta = atan(im / re);
            }
            
        }
    }

    bool mycomplex::operator==(const mycomplex& c) const
    {
        return r == c.r && theta == c.theta;
    }

    const mycomplex mycomplex::operator+(const mycomplex& c) const
    {
        mycomplex ret;
        ret.fromReIm(r*cos(theta) + c.r*cos(c.theta), r*sin(theta) + c.r*sin(c.theta));
        return ret;
    }

    const mycomplex mycomplex::operator*(const mycomplex& c) const
    {
        mycomplex ret;
        ret.r = r*c.r;
        ret.theta = theta + c.theta;
        ret.validate();
        return ret;
    }

    const mycomplex mycomplex::operator/(const mycomplex& c) const
    {
        mycomplex ret;
        ret.r = r / c.r;
        ret.theta = theta - c.theta;
        ret.validate();
        return ret;
    }

    const mycomplex& mycomplex::operator*=(const mycomplex& c)
    {
        *this = *this * c;
        return *this;
    }

    const mycomplex& mycomplex::operator/=(const mycomplex& c)
    {
        *this = *this / c;
        return *this;
    }

    const mycomplex& mycomplex::operator-=(const mycomplex& c)
    {
        *this = *this - c;
        return *this;
    }

    const mycomplex mycomplex::pow(double p) const
    {
        mycomplex ret;
        ret.r = ::pow(r, p);
        ret.theta = theta * p;
        ret.validate();
        return ret;
    }

    const mycomplex mycomplex::conj() const
    {
        mycomplex ret;
        ret.r = r;
        ret.theta = 2 * PI - theta;
        return ret;
    }

    ostream& mycomplex::print_p(ostream& os)
    {
        os << r << "*exp(" << theta << "i" << ")";
        return os;
    }

    void mycomplex::validate()
    {
        if (theta > 0)
        {
            while (theta > 2 *PI)
            {
                theta -= 2 * PI;
            }
        }
        else
        {
            while (theta / PI < 0)
            {
                theta += 2 * PI;
            }
        }
    }

    const mycomplex& mycomplex::operator+=(const mycomplex& c)
    {
        *this = *this + c;
        return *this;
    }

    const mycomplex mycomplex::operator-() const
    {
        mycomplex ret(r, ((theta <= PI) ? (theta + PI) : (theta - PI)));
        return ret;
    }

    const mycomplex mycomplex::operator-(const mycomplex& c) const
    {
        mycomplex ret;
        ret = *this + (-c);
        return ret;
    }

    const mycomplex& mycomplex::operator=(const mycomplex& c)
    {
        r=c.r;
        theta = c.theta;
        return *this;
    }

    ostream& operator<<(ostream &os, const mycomplex& c)
    {
        os << c.re();
        if (c.im()<0)
        {
            os << c.im() << "i";
        }
        if (c.im() > 0)
        {
            os << "+" << c.im() << "i";
        }
        return os;
    }

}    //namespace MyComplex

#endif

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM