/*! \file pifft.h * \brief Class for FFT, IFFT and Hilbert transformations */ /* PIP - Platform Independent Primitives Class for FFT, IFFT and Hilbert transformations Andrey Bychkov work.a.b@yandex.ru, Ivan Pelipenko peri4ko@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef PIFFT_H #define PIFFT_H #include "pip_fftw_export.h" #include "pimathcomplex.h" class PIP_EXPORT PIFFT_double { public: PIFFT_double(); PIVector * calcFFT(const PIVector &val); PIVector * calcFFT(const PIVector &val); PIVector * calcFFTinverse(const PIVector &val); PIVector * calcHilbert(const PIVector &val); PIVector getAmplitude() const; PIVector getReal() const; PIVector getImag() const; private: PIVector result; typedef ptrdiff_t ae_int_t; struct ftplan { PIVector plan; PIVector precomputed; PIVector tmpbuf; PIVector stackbuf; }; ftplan curplan; void fftc1d(const PIVector &a, uint n); void fftc1r(const PIVector &a, uint n); void fftc1dinv(const PIVector &a, uint n); void createPlan(uint n); void ftbasegeneratecomplexfftplan(uint n, ftplan *plan); void ftbase_ftbasegenerateplanrec(int n, int tasktype, ftplan *plan, int *plansize, int *precomputedsize, int *planarraysize, int *tmpmemsize, int *stackmemsize, ae_int_t stackptr, int debugi=0); void ftbase_ftbaseprecomputeplanrec(ftplan *plan, int entryoffset, ae_int_t stackptr); void ftbasefactorize(int n, int *n1, int *n2); void ftbase_ftbasefindsmoothrec(int n, int seed, int leastfactor, int *best); int ftbasefindsmooth(int n); void ftbaseexecuteplan(PIVector *a, int aoffset, int n, ftplan *plan); void ftbaseexecuteplanrec(PIVector *a, int aoffset, ftplan *plan, int entryoffset, ae_int_t stackptr); void ftbase_internalcomplexlintranspose(PIVector *a, int m, int n, int astart, PIVector *buf); void ftbase_ffticltrec(PIVector *a, int astart, int astride, PIVector *b, int bstart, int bstride, int m, int n); void ftbase_internalreallintranspose(PIVector *a, int m, int n, int astart, PIVector *buf); void ftbase_fftirltrec(PIVector *a, int astart, int astride, PIVector *b, int bstart, int bstride, int m, int n); void ftbase_ffttwcalc(PIVector *a, int aoffset, int n1, int n2); }; class PIP_EXPORT PIFFT_float { public: PIFFT_float(); PIVector * calcFFT(const PIVector &val); PIVector * calcFFT(const PIVector &val); PIVector * calcFFTinverse(const PIVector &val); PIVector * calcHilbert(const PIVector &val); PIVector getAmplitude() const; PIVector getReal() const; PIVector getImag() const; private: PIVector result; typedef ptrdiff_t ae_int_t; struct ftplan { PIVector plan; PIVector precomputed; PIVector tmpbuf; PIVector stackbuf; }; ftplan curplan; void fftc1d(const PIVector &a, uint n); void fftc1r(const PIVector &a, uint n); void fftc1dinv(const PIVector &a, uint n); void createPlan(uint n); void ftbasegeneratecomplexfftplan(uint n, ftplan *plan); void ftbase_ftbasegenerateplanrec(int n, int tasktype, ftplan *plan, int *plansize, int *precomputedsize, int *planarraysize, int *tmpmemsize, int *stackmemsize, ae_int_t stackptr, int debugi=0); void ftbase_ftbaseprecomputeplanrec(ftplan *plan, int entryoffset, ae_int_t stackptr); void ftbasefactorize(int n, int *n1, int *n2); void ftbase_ftbasefindsmoothrec(int n, int seed, int leastfactor, int *best); int ftbasefindsmooth(int n); void ftbaseexecuteplan(PIVector *a, int aoffset, int n, ftplan *plan); void ftbaseexecuteplanrec(PIVector *a, int aoffset, ftplan *plan, int entryoffset, ae_int_t stackptr); void ftbase_internalcomplexlintranspose(PIVector *a, int m, int n, int astart, PIVector *buf); void ftbase_ffticltrec(PIVector *a, int astart, int astride, PIVector *b, int bstart, int bstride, int m, int n); void ftbase_internalreallintranspose(PIVector *a, int m, int n, int astart, PIVector *buf); void ftbase_fftirltrec(PIVector *a, int astart, int astride, PIVector *b, int bstart, int bstride, int m, int n); void ftbase_ffttwcalc(PIVector *a, int aoffset, int n1, int n2); }; typedef PIFFT_double PIFFT; typedef PIFFT_double PIFFTd; typedef PIFFT_float PIFFTf; #ifndef CC_VC #define _PIFFTW_H(type) class PIP_FFTW_EXPORT _PIFFTW_P_##type##_ { \ public: \ _PIFFTW_P_##type##_(); \ ~_PIFFTW_P_##type##_(); \ const PIVector > & calcFFT(const PIVector > & in); \ const PIVector > & calcFFTR(const PIVector & in); \ const PIVector > & calcFFTI(const PIVector > & in); \ void preparePlan(int size, int op); \ void * impl; \ }; _PIFFTW_H(float) _PIFFTW_H(double) _PIFFTW_H(ldouble) template class PIFFTW { public: explicit PIFFTW() {p = 0; newP(p);} ~PIFFTW() {deleteP(p);} inline const PIVector > & calcFFT(const PIVector > & in) {return PIVector >().resize(in.size());} inline const PIVector > & calcFFT(const PIVector & in) {return PIVector >().resize(in.size());} inline const PIVector > & calcFFTinverse(const PIVector > & in) {return PIVector >().resize(in.size());} enum FFT_Operation {foReal, foComplex, foInverse}; inline void preparePlan(int size, FFT_Operation op) {} private: void operator =(const PIFFTW & ); PIFFTW(const PIFFTW &); inline void newP(void *& _p) {} inline void deleteP(void *& _p) {} void * p; }; template<> inline const PIVector > & PIFFTW::calcFFT(const PIVector > & in) {return ((_PIFFTW_P_float_*)p)->calcFFT(in);} template<> inline const PIVector > & PIFFTW::calcFFT(const PIVector & in) {return ((_PIFFTW_P_float_*)p)->calcFFTR(in);} template<> inline const PIVector > & PIFFTW::calcFFTinverse(const PIVector > & in) {return ((_PIFFTW_P_float_*)p)->calcFFTI(in);} template<> inline void PIFFTW::preparePlan(int size, FFT_Operation op) {((_PIFFTW_P_float_*)p)->preparePlan(size, op);} template<> inline void PIFFTW::newP(void *& _p) {_p = new _PIFFTW_P_float_();} template<> inline void PIFFTW::deleteP(void *& _p) {if (_p) delete (_PIFFTW_P_float_*)_p; _p = 0;} typedef PIFFTW PIFFTWf; template<> inline const PIVector > & PIFFTW::calcFFT(const PIVector > & in) {return ((_PIFFTW_P_double_*)p)->calcFFT(in);} template<> inline const PIVector > & PIFFTW::calcFFT(const PIVector & in) {return ((_PIFFTW_P_double_*)p)->calcFFTR(in);} template<> inline const PIVector > & PIFFTW::calcFFTinverse(const PIVector > & in) {return ((_PIFFTW_P_double_*)p)->calcFFTI(in);} template<> inline void PIFFTW::preparePlan(int size, FFT_Operation op) {((_PIFFTW_P_double_*)p)->preparePlan(size, op);} template<> inline void PIFFTW::newP(void *& _p) {_p = new _PIFFTW_P_double_();} template<> inline void PIFFTW::deleteP(void *& _p) {if (_p) delete (_PIFFTW_P_double_*)_p; _p = 0;} typedef PIFFTW PIFFTWd; template<> inline const PIVector > & PIFFTW::calcFFT(const PIVector > & in) {return ((_PIFFTW_P_ldouble_*)p)->calcFFT(in);} template<> inline const PIVector > & PIFFTW::calcFFT(const PIVector & in) {return ((_PIFFTW_P_ldouble_*)p)->calcFFTR(in);} template<> inline const PIVector > & PIFFTW::calcFFTinverse(const PIVector > & in) {return ((_PIFFTW_P_ldouble_*)p)->calcFFTI(in);} template<> inline void PIFFTW::preparePlan(int size, FFT_Operation op) {((_PIFFTW_P_ldouble_*)p)->preparePlan(size, op);} template<> inline void PIFFTW::newP(void *& _p) {_p = new _PIFFTW_P_ldouble_();} template<> inline void PIFFTW::deleteP(void *& _p) {if (_p) delete (_PIFFTW_P_ldouble_*)_p; _p = 0;} typedef PIFFTW PIFFTWld; #endif #endif // PIFFT_H