理解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