git-svn-id: svn://db.shs.com.ru/pip@331 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5

This commit is contained in:
2017-04-04 21:55:29 +00:00
parent d37c981d13
commit b6d35cf05b
5 changed files with 220 additions and 58 deletions

View File

@@ -150,7 +150,7 @@ if (FFTW)
if (WIN32) if (WIN32)
list(APPEND LIBS fftw3-3 fftw3f-3 fftw3l-3) list(APPEND LIBS fftw3-3 fftw3f-3 fftw3l-3)
else () else ()
list(APPEND LIBS fftw3 fftw3f) list(APPEND LIBS fftw3 fftw3f fftw3l)
endif () endif ()
else () else ()
message(STATUS "Building without fftw3 support") message(STATUS "Building without fftw3 support")

View File

@@ -31,7 +31,15 @@ const char pult_config[] =
connectionmodel = AAAM2Xja7VXLTttAFD12QpsikKjUSixYlLbKEpIUtVIlVEfqhk2FWuiGRRolUYtoHgrmpYiv6IItf8AveMMH9E/YsG6Ph3sde5hGoQoblLGuPHfunTPjc49nADxDA110+LTYC7FrPCAPeAO+vZu+aX7c/8PGd45WCJC0OGcfT6FDnmfSTPtwhZFt3HjgDs/Qtu5jPbZHtI/x50XfIzMQbdwEolbg9INP4ku++myPaUtCHYRaT2j1ldIh3VP60/Qff8vSfXLu9BP6JX9K/0TVH6jqVe22P1X/fao/oddWu/paDs1vBf9Jv/EZ91clbyHqv7BL6sscDOd4v4WTqs6jzaHGJ8QJerxlpJSpdZ7IWFJvDW7I2JxZqIM62k6A57RZmMQGmlyrxdV+WGBnmR01mXPI267hBKwp4FeBeo9VPtssxyb7rzHg1B7T9nCMU45U8BZlWuVWtIcD/CRGOqtsbW09851tXsHN0UTlLIAdASjSXnLyLn+H7L2+xbGYvC63Ezqg543egkLmn8qnRF6USbM4Qp9godkhzI777Ne5bCIt/5UtGz2o/yGby0nKpjqmbOa1ynkjmyzIrzvIZUeBPjvlUmbh32EFJbGyJZhR8YcvlS+3TpjhqeWSyvUkpbI9plSWtcKLcsK05beOJVEnhaEFfHEH+RwpeMcpn1JKGqWMNOL+G6wZyahlpdVOtufKfbDS+guLke9O\n\ connectionmodel = AAAM2Xja7VXLTttAFD12QpsikKjUSixYlLbKEpIUtVIlVEfqhk2FWuiGRRolUYtoHgrmpYiv6IItf8AveMMH9E/YsG6Ph3sde5hGoQoblLGuPHfunTPjc49nADxDA110+LTYC7FrPCAPeAO+vZu+aX7c/8PGd45WCJC0OGcfT6FDnmfSTPtwhZFt3HjgDs/Qtu5jPbZHtI/x50XfIzMQbdwEolbg9INP4ku++myPaUtCHYRaT2j1ldIh3VP60/Qff8vSfXLu9BP6JX9K/0TVH6jqVe22P1X/fao/oddWu/paDs1vBf9Jv/EZ91clbyHqv7BL6sscDOd4v4WTqs6jzaHGJ8QJerxlpJSpdZ7IWFJvDW7I2JxZqIM62k6A57RZmMQGmlyrxdV+WGBnmR01mXPI267hBKwp4FeBeo9VPtssxyb7rzHg1B7T9nCMU45U8BZlWuVWtIcD/CRGOqtsbW09851tXsHN0UTlLIAdASjSXnLyLn+H7L2+xbGYvC63Ezqg543egkLmn8qnRF6USbM4Qp9godkhzI777Ne5bCIt/5UtGz2o/yGby0nKpjqmbOa1ynkjmyzIrzvIZUeBPjvlUmbh32EFJbGyJZhR8YcvlS+3TpjhqeWSyvUkpbI9plSWtcKLcsK05beOJVEnhaEFfHEH+RwpeMcpn1JKGqWMNOL+G6wZyahlpdVOtufKfbDS+guLke9O\n\
"; ";
*/ */
#include "pifft.h"
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
PIFFTWf fft;
PIVector<float> in;
for (int i = 0; i < 32; ++i)
in << i%10;
PIVector<complexf> out = fft.calcFFT(in);
piCout << out;
return 0;
/*__S__ s, s1; /*__S__ s, s1;
s.text = "123"; s.text = "123";
s.i = -1; s.i = -1;

View File

@@ -18,6 +18,7 @@
*/ */
#include "pifft.h" #include "pifft.h"
#include "pifft_p.h"
PIFFT_double::PIFFT_double() { PIFFT_double::PIFFT_double() {
@@ -1892,3 +1893,17 @@ void PIFFT_float::ftbase_ffttwcalc(PIVector<float> * a, int aoffset, int n1, int
} }
} }
#define _PIFFTW_CPP(type) \
_PIFFTW_P_##type##_::_PIFFTW_P_##type##_() {impl = new PIFFTW_Private<type>();;} \
_PIFFTW_P_##type##_::~_PIFFTW_P_##type##_() {delete (PIFFTW_Private<type>*)impl;} \
const PIVector<complex<type> > & _PIFFTW_P_##type##_::calcFFT(const PIVector<complex<type> > & in) {return ((PIFFTW_Private<type>*)impl)->calcFFT(in);} \
const PIVector<complex<type> > & _PIFFTW_P_##type##_::calcFFTR(const PIVector<type> & in) {return ((PIFFTW_Private<type>*)impl)->calcFFT(in);} \
const PIVector<complex<type> > & _PIFFTW_P_##type##_::calcFFTI(const PIVector<complex<type> > & in) {return ((PIFFTW_Private<type>*)impl)->calcFFTinverse(in);} \
void _PIFFTW_P_##type##_::preparePlan(int size, int op) {return ((PIFFTW_Private<type>*)impl)->preparePlan(size, op);}
_PIFFTW_CPP(float)
_PIFFTW_CPP(double)
_PIFFTW_CPP(ldouble)

View File

@@ -122,74 +122,70 @@ typedef PIFFT_double PIFFTd;
typedef PIFFT_float PIFFTf; typedef PIFFT_float PIFFTf;
#define _PIFFTW_H(type) class _PIFFTW_P_##type##_ { \
// fftw3 realisation public: \
#ifdef PIP_FFTW _PIFFTW_P_##type##_(); \
#include <complex.h> ~_PIFFTW_P_##type##_(); \
#include "fftw3.h" const PIVector<complex<type> > & calcFFT(const PIVector<complex<type> > & in); \
#include "pimutex.h" const PIVector<complex<type> > & calcFFTR(const PIVector<type> & in); \
const PIVector<complex<type> > & calcFFTI(const PIVector<complex<type> > & in); \
static PIMutex __pip_fft_plan_mutex; void preparePlan(int size, int op); \
void * impl; \
};
_PIFFTW_H(float)
_PIFFTW_H(double)
_PIFFTW_H(ldouble)
template <typename T> template <typename T>
class PIP_EXPORT PIFFTW class PIP_EXPORT PIFFTW
{ {
public: public:
const PIVector<complex<T> > & calcFFT(const PIVector<complex<T> > &in) { explicit PIFFTW() {p = 0; newP(p);}
result.resize(in.size()); ~PIFFTW() {deleteP(p);}
__pip_fft_plan_mutex.lock(); const PIVector<complex<T> > & calcFFT(const PIVector<complex<T> > & in) {return PIVector<complex<T> >().resize(in.size());}
p = fftw_plan_dft_1d(in.size_s(), (fftw_complex *)in.data(), (fftw_complex *)result.data(), FFTW_FORWARD, FFTW_ESTIMATE); const PIVector<complex<T> > & calcFFT(const PIVector<T> & in) {return PIVector<complex<T> >().resize(in.size());}
__pip_fft_plan_mutex.unlock(); const PIVector<complex<T> > & calcFFTinverse(const PIVector<complex<T> > & in) {return PIVector<complex<T> >().resize(in.size());}
fftw_execute(p);
fftw_destroy_plan(p);
return result;
}
const PIVector<complex<T> > & calcFFT(const PIVector<T> &in) {
result.resize(in.size());
__pip_fft_plan_mutex.lock();
p = fftw_plan_dft_r2c_1d(in.size_s(), (double *)in.data(), (fftw_complex *)result.data(), FFTW_ESTIMATE);
__pip_fft_plan_mutex.unlock();
fftw_execute(p);
fftw_destroy_plan(p);
return result;
}
const PIVector<complex<T> > & calcFFTinverse(const PIVector<complex<T> > &in) {
result.resize(in.size());
__pip_fft_plan_mutex.lock();
p = fftw_plan_dft_1d(in.size_s(), (fftw_complex *)in.data(), (fftw_complex *)result.data(), FFTW_BACKWARD, FFTW_ESTIMATE);
__pip_fft_plan_mutex.unlock();
fftw_execute(p);
fftw_destroy_plan(p);
return result;
}
enum FFT_Operation {fo_real, fo_complex, fo_inverse}; enum FFT_Operation {foReal, foComplex, foInverse};
void preparePlan(int size, FFT_Operation op) { void preparePlan(int size, FFT_Operation op) {}
PIVector<complex<T> > in(size), out(size);
PIVector<T> inr(size);
__pip_fft_plan_mutex.lock();
switch (op) {
case fo_real:
p = fftw_plan_dft_r2c_1d(in.size_s(), (double *)inr.data(), (fftw_complex *)out.data(), FFTW_MEASURE);
break;
case fo_complex:
p = fftw_plan_dft_1d(in.size_s(), (fftw_complex *)in.data(), (fftw_complex *)out.data(), FFTW_FORWARD, FFTW_MEASURE);
break;
case fo_inverse:
p = fftw_plan_dft_1d(in.size_s(), (fftw_complex *)in.data(), (fftw_complex *)out.data(), FFTW_BACKWARD, FFTW_MEASURE);
break;
}
__pip_fft_plan_mutex.unlock();
}
private: private:
PIVector<complex<T> > result; void operator =(const PIFFTW & );
fftw_plan p; inline void newP(void *& _p) {}
inline void deleteP(void *& _p) {}
void * p;
}; };
typedef PIFFTW<double> PIFFTWd;
#endif // PIP_FFTW template<> const PIVector<complex<float> > & PIFFTW<float>::calcFFT(const PIVector<complex<float> > & in) {return ((_PIFFTW_P_float_*)p)->calcFFT(in);}
template<> const PIVector<complex<float> > & PIFFTW<float>::calcFFT(const PIVector<float> & in) {return ((_PIFFTW_P_float_*)p)->calcFFTR(in);}
template<> const PIVector<complex<float> > & PIFFTW<float>::calcFFTinverse(const PIVector<complex<float> > & in) {return ((_PIFFTW_P_float_*)p)->calcFFTI(in);}
template<> void PIFFTW<float>::preparePlan(int size, FFT_Operation op) {((_PIFFTW_P_float_*)p)->preparePlan(size, op);}
template<> inline void PIFFTW<float>::newP(void *& _p) {_p = new _PIFFTW_P_float_();}
template<> inline void PIFFTW<float>::deleteP(void *& _p) {if (_p) delete (_PIFFTW_P_float_*)_p; _p = 0;}
template<> const PIVector<complex<double> > & PIFFTW<double>::calcFFT(const PIVector<complex<double> > & in) {return ((_PIFFTW_P_double_*)p)->calcFFT(in);}
template<> const PIVector<complex<double> > & PIFFTW<double>::calcFFT(const PIVector<double> & in) {return ((_PIFFTW_P_double_*)p)->calcFFTR(in);}
template<> const PIVector<complex<double> > & PIFFTW<double>::calcFFTinverse(const PIVector<complex<double> > & in) {return ((_PIFFTW_P_double_*)p)->calcFFTI(in);}
template<> void PIFFTW<double>::preparePlan(int size, FFT_Operation op) {((_PIFFTW_P_double_*)p)->preparePlan(size, op);}
template<> inline void PIFFTW<double>::newP(void *& _p) {_p = new _PIFFTW_P_double_();}
template<> inline void PIFFTW<double>::deleteP(void *& _p) {if (_p) delete (_PIFFTW_P_double_*)_p; _p = 0;}
template<> const PIVector<complex<ldouble> > & PIFFTW<ldouble>::calcFFT(const PIVector<complex<ldouble> > & in) {return ((_PIFFTW_P_ldouble_*)p)->calcFFT(in);}
template<> const PIVector<complex<ldouble> > & PIFFTW<ldouble>::calcFFT(const PIVector<ldouble> & in) {return ((_PIFFTW_P_ldouble_*)p)->calcFFTR(in);}
template<> const PIVector<complex<ldouble> > & PIFFTW<ldouble>::calcFFTinverse(const PIVector<complex<ldouble> > & in) {return ((_PIFFTW_P_ldouble_*)p)->calcFFTI(in);}
template<> void PIFFTW<ldouble>::preparePlan(int size, FFT_Operation op) {((_PIFFTW_P_ldouble_*)p)->preparePlan(size, op);}
template<> inline void PIFFTW<ldouble>::newP(void *& _p) {_p = new _PIFFTW_P_ldouble_();}
template<> inline void PIFFTW<ldouble>::deleteP(void *& _p) {if (_p) delete (_PIFFTW_P_ldouble_*)_p; _p = 0;}
typedef PIFFTW<float> PIFFTWf;
typedef PIFFTW<double> PIFFTWd;
typedef PIFFTW<ldouble> PIFFTWld;
#endif // PIFFT_H #endif // PIFFT_H

143
src/math/pifft_p.h Normal file
View File

@@ -0,0 +1,143 @@
/*! \file pifft_p.h
* \brief Class for FFT, IFFT and Hilbert transformations
*/
/*
PIP - Platform Independent Primitives
Private header for fftw3
Copyright (C) 2017 Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIFFT_P_H
#define PIFFT_P_H
#include "pivector.h"
#include "pimutex.h"
#include <complex.h>
#ifdef PIP_FFTW
# include "fftw3.h"
#else
# define FFTW_FORWARD 0
# define FFTW_BACKWARD 0
# define FFTW_ESTIMATE 0
# define FFTW_MEASURE 0
#endif
static PIMutex __pip_fft_plan_mutex;
template <typename T>
class PIFFTW_Private
{
public:
explicit PIFFTW_Private() {plan = 0; newPlan(plan);}
~PIFFTW_Private() {deletePlan(plan);}
const PIVector<complex<T> > & calcFFT(const PIVector<complex<T> > & in) {
result.resize(in.size());
__pip_fft_plan_mutex.lock();
createPlan_c_1d(plan, in.size_s(), in.data(), result.data(), FFTW_FORWARD, FFTW_ESTIMATE);
__pip_fft_plan_mutex.unlock();
executePlan(plan);
destroyPlan(plan);
return result;
}
const PIVector<complex<T> > & calcFFT(const PIVector<T> & in) {
result.resize(in.size());
__pip_fft_plan_mutex.lock();
createPlan_r2c_1d(plan, in.size_s(), in.data(), result.data(), FFTW_ESTIMATE);
__pip_fft_plan_mutex.unlock();
executePlan(plan);
destroyPlan(plan);
return result;
}
const PIVector<complex<T> > & calcFFTinverse(const PIVector<complex<T> > & in) {
result.resize(in.size());
__pip_fft_plan_mutex.lock();
createPlan_c_1d(plan, in.size_s(), in.data(), result.data(), FFTW_BACKWARD, FFTW_ESTIMATE);
__pip_fft_plan_mutex.unlock();
executePlan(plan);
destroyPlan(plan);
return result;
}
enum FFT_Operation {fo_real, fo_complex, fo_inverse};
void preparePlan(int size, int op) {
PIVector<complex<T> > in(size), out(size);
PIVector<T> inr(size);
__pip_fft_plan_mutex.lock();
switch ((FFT_Operation)op) {
case fo_real:
createPlan_r2c_1d(plan, in.size_s(), inr.data(), out.data(), FFTW_MEASURE);
break;
case fo_complex:
createPlan_c_1d(plan, in.size_s(), in.data(), out.data(), FFTW_FORWARD, FFTW_MEASURE);
break;
case fo_inverse:
createPlan_c_1d(plan, in.size_s(), in.data(), out.data(), FFTW_BACKWARD, FFTW_MEASURE);
break;
}
__pip_fft_plan_mutex.unlock();
}
inline void createPlan_c_1d(void * plan, int size, const void * in, void * out, int dir, int flags) {}
inline void createPlan_r2c_1d(void * plan, int size, const void * in, void * out, int flags) {}
inline void executePlan(void * plan) {}
inline void destroyPlan(void * plan) {}
inline void newPlan(void *& plan) {}
inline void deletePlan(void *& plan) {}
PIVector<complex<T> > result;
void * plan;
};
#ifdef PIP_FFTW
template<> inline void PIFFTW_Private<float>::createPlan_c_1d(void * plan, int size, const void * in, void * out, int dir, int flags) {
*(fftwf_plan*)plan = fftwf_plan_dft_1d(size, (fftwf_complex *)in, (fftwf_complex *)out, dir, flags);}
template<> inline void PIFFTW_Private<float>::createPlan_r2c_1d(void * plan, int size, const void * in, void * out, int flags) {
*(fftwf_plan*)plan = fftwf_plan_dft_r2c_1d(size, (float *)in, (fftwf_complex *)out, flags);}
template<> inline void PIFFTW_Private<float>::executePlan(void * plan) {fftwf_execute(*(fftwf_plan*)plan);}
template<> inline void PIFFTW_Private<float>::destroyPlan(void * plan) {fftwf_destroy_plan(*(fftwf_plan*)plan);}
template<> inline void PIFFTW_Private<float>::newPlan(void *& plan) {plan = new fftwf_plan();}
template<> inline void PIFFTW_Private<float>::deletePlan(void *& plan) {if (plan) delete (fftwf_plan*)plan; plan = 0;}
template<> inline void PIFFTW_Private<double>::createPlan_c_1d(void * plan, int size, const void * in, void * out, int dir, int flags) {
*(fftw_plan*)plan = fftw_plan_dft_1d(size, (fftw_complex *)in, (fftw_complex *)out, dir, flags);}
template<> inline void PIFFTW_Private<double>::createPlan_r2c_1d(void * plan, int size, const void * in, void * out, int flags) {
*(fftw_plan*)plan = fftw_plan_dft_r2c_1d(size, (double *)in, (fftw_complex *)out, flags);}
template<> inline void PIFFTW_Private<double>::executePlan(void * plan) {fftw_execute(*(fftw_plan*)plan);}
template<> inline void PIFFTW_Private<double>::destroyPlan(void * plan) {fftw_destroy_plan(*(fftw_plan*)plan);}
template<> inline void PIFFTW_Private<double>::newPlan(void *& plan) {plan = new fftw_plan();}
template<> inline void PIFFTW_Private<double>::deletePlan(void *& plan) {if (plan) delete (fftw_plan*)plan; plan = 0;}
template<> inline void PIFFTW_Private<ldouble>::createPlan_c_1d(void * plan, int size, const void * in, void * out, int dir, int flags) {
*(fftwl_plan*)plan = fftwl_plan_dft_1d(size, (fftwl_complex *)in, (fftwl_complex *)out, dir, flags);}
template<> inline void PIFFTW_Private<ldouble>::createPlan_r2c_1d(void * plan, int size, const void * in, void * out, int flags) {
*(fftwl_plan*)plan = fftwl_plan_dft_r2c_1d(size, (ldouble *)in, (fftwl_complex *)out, flags);}
template<> inline void PIFFTW_Private<ldouble>::executePlan(void * plan) {fftwl_execute(*(fftwl_plan*)plan);}
template<> inline void PIFFTW_Private<ldouble>::destroyPlan(void * plan) {fftwl_destroy_plan(*(fftwl_plan*)plan);}
template<> inline void PIFFTW_Private<ldouble>::newPlan(void *& plan) {plan = new fftwl_plan();}
template<> inline void PIFFTW_Private<ldouble>::deletePlan(void *& plan) {if (plan) delete (fftwl_plan*)plan; plan = 0;}
#endif // PIP_FFTW
#endif // PIFFT_H