Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

fft.cpp

Go to the documentation of this file.
00001 #include "fft.hpp"
00002 #include <math.h>
00003 
00004 /*=========Complex=======*/
00005 
00006 Complex::Complex(double _re, double _im) 
00007     : re(_re), im(_im) { }
00008 
00009 double Complex::GetRe() const
00010 {
00011     return re;
00012 }
00013 
00014 double Complex::GetIm() const
00015 {
00016     return im;
00017 }
00018 
00019 double Complex::GetNorm() const
00020 {
00021     return re * re + im * im;
00022 }
00023 
00024 Complex Complex::operator+(const Complex &op2) const
00025 {
00026     Complex res(re + op2.re, im + op2.im);
00027     return res;
00028 }
00029 
00030 Complex Complex::operator-(const Complex &op2) const
00031 {
00032     Complex res(re - op2.re, im - op2.im);
00033     return res;
00034 }
00035 
00036 Complex Complex::operator*(const Complex &op2) const
00037 {
00038     Complex res(re * op2.re - im * op2.im,
00039                 re * op2.im + im * op2.re);
00040     return res;
00041 }
00042 
00043 Complex Complex::operator/(const Complex &op2) const
00044 {
00045     double dvs = op2.GetNorm();
00046     Complex res((re * op2.re + im * op2.im) / dvs,
00047                 (im * op2.re - re * op2.im) / dvs);
00048     return res;
00049 }
00050 
00051 void Complex::operator+=(const Complex &op2)
00052 {
00053         re += op2.re;
00054         im += op2.im;
00055 }
00056 
00057 void Complex::operator*=(const Complex &op2)
00058 {
00059     double tmp;
00060     tmp = re * op2.re - im * op2.im;
00061     im = re * op2.im + im * op2.re;
00062     re = tmp;
00063 }
00064 
00065 void Complex::operator/=(const Complex &op2) {
00066     double tmp, dvs = op2.GetNorm();
00067     tmp = (re * op2.re + im * op2.im) / dvs;
00068     im = (im * op2.re - re * op2.im) / dvs;
00069     re = tmp;
00070 }
00071 
00072 /*=====FourierTransform====*/
00073 
00074 FourierTransform::FourierTransform(unsigned _k)
00075     : k(_k), rev(0)
00076 {
00077     N = 1 << k;
00078 }
00079 
00080 FourierTransform::~FourierTransform()
00081 {
00082     if(rev) {
00083         delete [] rev;
00084     }
00085 }
00086 
00087 void FourierTransform::set_reverse()
00088 {
00089     unsigned i, h;
00090     h = -1;
00091     rev[0] = 0;
00092     for(i = 1; i < N; ++i) {
00093         /* h = floor(log_{2}{i}} */
00094         if((i & (i - 1)) == 0) {
00095             /* if i is a power of 2 */
00096             h++;
00097         }
00098         rev[i] = rev[i ^ (1 << h)];
00099         rev[i] |= (1 << (k - h - 1));
00100     }
00101 }
00102 
00103 void FourierTransform::Matvec(const Complex *vec, Complex *res, 
00104             mv_mode mode) const
00105 {
00106     unsigned m, p;
00107     double a = -2.0 * M_PI / N;
00108     if(mode == conj) {
00109         a *= -1;
00110     }
00111     Complex w;
00112     for(m = 0; m < N; ++m) {
00113         res[m] = 0;
00114         for(p = 0; p < N; ++p) {
00115             w = Complex(cos(a * p * m), sin(a * p * m));
00116             res[m] += vec[p] * w;
00117         }
00118     }
00119 }
00120 
00121 void FourierTransform::MatvecFast(const Complex *vec, Complex *res, 
00122             mv_mode mode)
00123 {
00124     unsigned m, p, j;
00125     Complex t, u, w, wm;
00126     double a = -2.0 * M_PI;
00127     if(mode == conj) {
00128         a *= -1;
00129     }
00130     if(!rev) {
00131         rev = new unsigned[N];
00132         set_reverse();
00133     }
00134     for(m = 0; m < N; ++m) {
00135         res[m] = vec[rev[m]];
00136     }
00137     
00138     for(m = 1; m <= N; m *= 2) {
00139         wm = Complex(cos(a / m), sin(a / m));
00140         for(p = 0; p < N; p += m) {
00141             w = 1;
00142             for(j = 0; j < m / 2; ++j) {
00143                 t = w * res[p + j + m / 2];
00144                 u = res[p + j];
00145                 res[p + j] = u + t;
00146                 res[p + j + m / 2] = u - t;
00147                 w *= wm;
00148             }
00149         }
00150     }
00151 }

Generated on Sun May 25 01:58:04 2025 for SmoluchowskiSolver by Doxygen