/*! \file pifft.h * \ingroup Math * \ingroup FFTW * \~\brief * \~english FFT, IFFT and Hilbert transformations * \~russian БПФ, ОБПФ и преобразования Гильберта */ /* 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 . */ //! \defgroup FFTW FFTW //! \~\brief //! \~english Optimized FFT support via libfftw3 //! \~russian Оптимизированный БПФ с помощью libfftw3 //! //! \~\details //! \~english \section cmake_module_FFTW Building with CMake //! \~russian \section cmake_module_FFTW Сборка с использованием CMake //! //! \~\code //! find_package(PIP REQUIRED) //! target_link_libraries([target] PIP::FFTW) //! \endcode //! //! \~english \par Common //! \~russian \par Общее //! //! \~english //! These files provides FFT using [libfftw3](https://fftw.org/) //! //! \~russian //! Эти файлы обеспечивают БПФ с использованием [libfftw3](https://fftw.org/) //! //! \~\authors //! \~english //! Ivan Pelipenko peri4ko@yandex.ru; //! Andrey Bychkov work.a.b@yandex.ru; //! \~russian //! Иван Пелипенко peri4ko@yandex.ru; //! Андрей Бычков work.a.b@yandex.ru; //! #ifndef PIFFT_H #define PIFFT_H #include "pimathcomplex.h" #ifndef MICRO_PIP # include "pip_fftw_export.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 // MICRO_PIP #endif // PIFFT_H