最近在看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